如何从所选键再次迭代python dict?
Posted
技术标签:
【中文标题】如何从所选键再次迭代python dict?【英文标题】:How to iterate over python dict from the chosen key to it again? 【发布时间】:2021-05-09 02:39:51 【问题描述】:用一个例子更容易解释,让我的问题更清楚:
例如:
example_dict = 1 : "A", 2 : "B", 3 : "C", 4 : "D", 5 : "E"
假设我想在键 3 上开始迭代,以便获得相应的值,直到再次迭代为止。
# Chosen the key = 3 will return:
["C","D","E","A","B"]
那么从一个键迭代到自身的最佳方法是什么?
迭代是否应该到达字典的末尾并从头开始迭代,直到找到最初选择的键?
另一个例子:
example_dict = 23 : "Hello", 3 : "Bye", 11 : "Shame", 45 : "Nice", 2 : "Pretty"
# Chosen the key = 3 will return:
["Bye","Shame","Nice","Pretty","Hello"]
【问题讨论】:
字典实际上并没有键顺序的概念(至少在 python 3.8 之前没有)。因此,如果您有一个包含要按正确顺序访问的键的列表,那么您可以完成此操作。不然 dicts 在 python 3.6 @inspectorG4dget 之后排序 使用list(example_dict.keys())
获取列表中的键。然后您可以旋转该列表并遍历它。
具有顺序编号键的字典似乎是一种反模式。为什么不只是一个列表?
@Jab 是迂腐的,它们在 Python 3.6 中作为实现细节被订购,由 Python 3.7+ 中的语言保证
【参考方案1】:
一种使用itertools
的方法:
您实际上想通过 key 来执行此操作,因此只需先找到键的“索引”并使用它(准确地说,是从键创建的列表的索引)。使用 itertools 中的 cycle
和 islice
创建一个迭代器,使用键的位置和字典的大小:
>>> idx = list(example_dict).index(3)
>>> list(islice(cycle(example_dict.values()), idx, idx + len(example_dict)))
['C', 'D', 'E', 'A', 'B']
【讨论】:
【参考方案2】:你可以使用dict.values
然后对列表使用切片:
val_list = list(example_dict.values())
output = val_list[2:] + val_list[:2]
['C', 'D', 'E', 'A', 'B']
要找到3
的索引,将字典变成一个列表并使用list.index
:
>>> list(example_dict).index(3)
2
【讨论】:
【参考方案3】:虽然你可以使用自己的函数来实现,但这是不正常的
def get_elements(dictionary, key):
l = list(dictionary.items())
for i in range(len(l)):
if(l[i][0] == key): # check if this the required key
return[e[1] for e in l[i:] + l[0:i]]
输出
d = 1 : "A", 2 : "B", 3 : "C", 4 : "D", 5 : "E"
get_elements(d, 3)
['C', 'D', 'E', 'A', 'B']
【讨论】:
【参考方案4】:您可以结合 itertools 中的几个函数在列表推导中仅使用迭代器而不创建中间列表:
from itertools import dropwhile,takewhile
d = 1 : "A", 2 : "B", 3 : "C", 4 : "D", 5 : "E"
K = 3
r = (v for f in (dropwhile,takewhile) for _,v in f(lambda k:k[0]!=K,d.items()))
print(type(r)) # <class 'generator'>
print(*r) # C D E A B
其工作方式是使用 dropwhile 获取指定键 (K
) 中的值直到结束,然后使用 takewhile 获取键之前的值。因为这两个函数具有相同的签名并应用相同的条件,所以它们可以作为列表理解的一部分,作为选择要应用于字典的函数的第一级。
这种方法产生一个生成器。如果您需要一个列表,您可以将理解用方括号而不是括号括起来。
d = 23 : "Hello", 3 : "Bye", 11 : "Shame", 45 : "Nice", 2 : "Pretty"
K = 3
r = [v for f in (dropwhile,takewhile) for _,v in f(lambda k:k[0]!=K,d.items())]
print(r) # ['Bye', 'Shame', 'Nice', 'Pretty', 'Hello']
也可以在没有任何库模块的情况下通过创建一个键列表来查找起始键的位置并在双倍字典的子范围中迭代:
r = [d[k] for i,k in enumerate((*d,*d),-[*d].index(key)) if i in range(len(d))]
【讨论】:
以上是关于如何从所选键再次迭代python dict?的主要内容,如果未能解决你的问题,请参考以下文章