如果值出现在元组列表中,则条件为真

while condition true if value appears in list of tuples

我是 Python 的新手,在实现绘制图形的算法时卡住了。我有一个包含某些节点及其 'level' (用于分层)的元组列表。最初看起来像这样:

[(0, 10), (1, 'empty'), (2, 'empty'), (3, 'empty'), (4, 'empty'), (5, 'empty'), (6, 'empty'), (7, 'empty'), (8, 'empty'), (9, 'empty')](节点,级别)

现在我需要为这些节点分配级别,只要任何节点都没有级别,相应的 'empty' 属性。

我尝试了几种可能的 while 条件结构,它们在语法上没有错,但在语义上没有任何意义,因为 while 循环没有终止:

while (True for node, level in g.nodes(data='level') if level == 'empty'):

while ( 'empty' in enumerate(g.nodes(data='level') ):

和某些其他类似的构造,它们没有用,我不记得了..

直到现在我还不清楚为什么这行不通 - python 在这些条件下甚至没有进入 while 循环。你能解释一下原因并告诉我如何解决吗?

提示: g.nodes(data='level') 是一个networkx函数,即returns元组的上层列表

如果您只是想为每个级别分配一个空的级别,那么一个简单的 for 循环就足够了:

data = [(0, 10), (1, 'empty'), (2, 'empty'), (3, 'empty'), (4, 'empty'), (5, 'empty'), (6, 'empty'), (7, 'empty'), (8, 'empty'), (9, 'empty')]
output = []

for node, level in data:
    if level == 'empty':
        level = ? #question mark is whatever level logic you wish to insert
    output.append((node, level))

使用 for 循环通常更符合 Pythonic:

nodes = [(0, 10),
         (1, 'empty'),
         (2, 'empty'),
         (3, 'empty'),
         (4, 'empty'),
         (5, 'empty'),
         (6, 'empty'),
         (7, 'empty'),
         (8, 'empty'),
         (9, 'empty')]

for node in nodes:
    if node[1]=="empty":
        node[1] = set_level_func() # customise this function as you wish
    

因此括号中的内容是 生成器表达式 并且它们总是计算为 True.

您的想法是正确的,但可能需要更多地了解这些表达式以及如何使用它们。在您的第一个建议中,这是我_认为_您的意思:

while any(level == 'empty' for node, level in g.nodes(data='level')):
  ...

在您的版本中,您所做的是创建一个 生成器表达式 ,它将包含许多 True 个值,每个级别对应 empty.但是,即使该生成器表达式中没有任何元素,它本身也不是一个空对象,因此它的计算结果为 True.

你可以试试这个:

bool([]) # --> False because empty sequence
bool(list(range(1, -10))) # --> False because empty sequence
bool((i for i in range(1,-10))) # --> True because non-None generator expression

所以你需要把你的生成器表达式变成一个真值,这个真值实际上反映了它是否有任何真正的元素,这就是 any 函数所做的:取一个迭代器(或生成器表达式) return 如果其中任何元素为真,则为真。

您正在尝试进行元素检查以进行搜索。相反,专注于准确提取您需要检查的值。让我们从元组列表开始 as

g = [(0, 10), (1, 'empty'), (2, 'empty'), (3, 'empty'), (4, 'empty'),
     (5, 'empty'), (6, 'empty'), (7, 'empty'), (8, 'empty'), (9, 'empty')]

现在只获取关卡列表:

level = [node[1] for node in g]

现在,您的支票很简单

while "empty" in level:
    # Assign levels as appropriate
    # Repeat the check for "empty"
    level = [node[1] for node in g]

如果您持续更新主图,g,则将级别提取折叠到 while:

while "empty" in [node[1] for node in g]:
    # Assign levels

最初,你的 while 失败是因为你 return True 只要 g:

中有任何内容
while (True for node, level in ...)

你有一个很好的方法,但是把它弄得太复杂了,并且卡在了True

您的 enumerate 尝试失败,因为您在枚举器中搜索字符串,而不是在其 returned 值中搜索。您可以制作一个 returned 值的列表,但是我们又回到了我们开始的地方,有一个元组列表。这会将“空”与每个元组进行比较,并且无法找到所需的字符串——它在下一级。

其他答案可能是最好的。但是你要求的具体测试可以写成几种方式:

这与您之前的类似,但创建的是列表而不是生成器。如果列表为空,则该列表将评估为 False,但生成器不会。

while [True for node, level in g.nodes(data='level') if level == 'empty']:
   ...

这是一个同样有效的版本。该列表必须为空或不为空;元素是 True 还是 False 或其他什么并不重要:

while [node for node, level in g.nodes(data='level') if level == 'empty']:
   ...

或者您可以使用 Python 的 any 函数,该函数是为此而设计的,效率会更高一些(它会在第一次匹配后停止检查元素)。这可以使用生成器或列表。

while any(level == 'empty' for node, level in g.nodes(data='level')):
   ...