![](/img/trans.png)
[英]Create a list of tuples with adjacent list elements if a condition is true
[英]while condition true if value appears in list of tuples
我是 Python 的新手,在實現繪制圖形的算法時被卡住了。 我有一個包含某些節點及其“級別”(用於分層)的元組列表。 最初看起來像這樣:
[(0, 10), (1, 'empty'), (2, 'empty'), (3, 'empty'), (4, 'empty'), (5, 'empty'), (6, 'empty'), (7, 'empty'), (8, 'empty'), (9, 'empty')]
(node,level)
現在我需要為這些節點分配級別,只要任何節點沒有級別,相應的“空”屬性。
我嘗試了幾種可能的 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 function,它返回元組的上層列表
因此,括號中的內容是生成器表達式,它們總是評估為True
。
你有正確的想法,但可能需要更多地了解這些表達式以及如何處理它們。 在您的第一個建議中,我_認為_您的意思是:
while any(level == 'empty' for node, level in g.nodes(data='level')):
...
在您的版本中,您所做的是創建一個生成器表達式,該表達式將包含多個True
值,每個級別一個為empty
。 但是,即使該生成器表達式中沒有元素,它本身也不是一個空的 object,因此它的計算結果為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
function 所做的:取一個迭代器(或一個生成器表達式)並返回 true 如果它的任何元素是真的。
你正試圖通過元素檢查來尋找你。 相反,專注於准確提取您需要檢查的值。 讓我們從元組列表開始
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
失敗了,因為只要g
中有任何內容,您就會返回True
:
while (True for node, level in ...)
你有一個很好的方法,但是讓它太復雜了一層,並且被True
卡住了。
您的enumerate
嘗試失敗,因為您在枚舉器中搜索字符串,而不是在其返回值中。 您可以制作一個返回值的列表,但是我們又回到了我們開始的地方,帶有一個元組列表。 這會將“空”與每個元組進行比較,並且無法找到所需的字符串——它比下一層更遠。
其他答案可能是最好的。 但是您要求的具體測試可以寫成幾種方式:
這與您所擁有的類似,但創建了一個列表而不是生成器。 如果列表為空,則列表將評估為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
function,它是為此而設計的,並且效率更高(它在第一次匹配后停止檢查元素)。 這可以使用生成器或列表。
while any(level == 'empty' for node, level in g.nodes(data='level')):
...
如果您只是想為每個級別分配級別,如果一個為空,那么一個簡單的 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.