简体   繁体   English

提前更新字典列表

[英]Lookahead updating a list of dictionaries

I have a list of dictionaries that looks like this:我有一个看起来像这样的字典列表:

someList = [{'a':3}, {'a':4}, {'a':6}]

Assuming that the length of someList is >1000, what is the most efficient and pythonic way to obtain the following list of dictionaries:假设someList的长度 >1000,那么获取以下字典列表的最有效和 Pythonic 方法是什么:

someList = [{'prev_a':0, 'a': 3 , 'next_a': 4}, {'prev_a':3, 'a':4 , 'next_a' : 6}, {'prev_a':4, 'a': 6 , 'next_a': 0}]

Where:在哪里:

  • next_a has the value of a in the succeeding dictionary and next_a在后续字典中具有 a 的值,并且

  • prev_a has the value of a in the preceding dictionary prev_a具有前面字典中 a 的值

  • first and last values for prev_a and next_a, respectively, can be 0 prev_a 和 next_a 的 first 和 last 值分别可以为 0

Update 1:更新1:

The number of variables, such as a can be more than one;变量的个数,比如a可以多于一个; the dictionary could look like this:字典可能如下所示:

someList = [{'a':2,'b':4,'c':9}]
dict_key_values = ['a','c']

In this case the list I want to get should only feature the prev_ and next_ values of a and c在这种情况下,我想获得的列表应该只包含acprev_next_

someList = [{'prev_a':4, 'a': 6 , 'next_a': 0, 'prev_c':4, 'c': 3 , 'next_c': 0, 'b':1}, ...]

(Without the use of Pandas) (不使用熊猫)

Edit编辑

My initial approach was to enumerate(someList) , use someList[i-1]['a'] and someList[i+1]['a'] to access the element before and after to get prev_a and next_a.我最初的方法是enumerate(someList) ,使用someList[i-1]['a']someList[i+1]['a']访问之前和之后的元素以获取 prev_a 和 next_a。

The problem with this approach is that when the number of variables such as a increase, the code becomes hard to manage这种方法的问题在于,当变量等a增加时,代码变得难以管理

You can use itertools to get multiple iterators over the same list.您可以使用itertools在同一个列表上获取多个迭代器。 Then it only has to take up memory for the current elements.然后它只需要为当前元素占用memory。 You can use islice to skip one, and chain to prepend one.您可以使用islice跳过一个,并使用chain前置一个。 Then zip them together into triples to iterate over all three offsets at once.然后 zip 将它们组合成三元组,一次遍历所有三个偏移量。

If you like, you can use a comprehension to build the triples into dicts.如果您愿意,可以使用推导式将三元组构建成 dicts。 (But depending on your use case, it might be more time-efficient to skip this step and use the triples directly.) (但根据您的用例,跳过此步骤并直接使用三元组可能更省时。)

from itertools import chain, islice, zip_longest

def lookahead(someList, dict_key_values):
    filldict = dict.fromkeys(dict_key_values, 0)
    prefixes = ["prev_", "next_"]
    return [
        {prefix+k: v
         for prefix, d in zip(prefixes, [p, n])
         for k, v in d.items() if k in filldict}
        | c
        for p, c, n in
        zip_longest(
            chain([filldict], someList),
            someList,
            islice(someList, 1, None),
            fillvalue=filldict,
        )
    ]

The zip_longest will fill in extra values after the iterators are exhausted up till the longest one. zip_longest将在迭代器耗尽直到最长的值后填充额外的值。

>>> someList = [{'a':2,'b':4,'c':9}]
>>> dict_key_values = ['a','c']
>>> lookahead(someList, dict_key_values)
[{'prev_a': 0, 'prev_c': 0, 'next_a': 0, 'next_c': 0, 'a': 2, 'b': 4, 'c': 9}, {'prev_a': 2, 'prev_c': 9, 'next_a': 0, 'next_c': 0, 'a': 0, 'c': 0}]

If you prefer to stop at the shortest one (the islice in this case), use the builtin zip instead (and omit the fillvalue ).如果您更喜欢停在最短的一个(在这种情况下为islice ),请改用内置zip (并省略fillvalue )。

Depending on how you are planning to access the content of the list, i would think an implementaiton of a doubly linked list would be a good option.根据您计划访问列表内容的方式,我认为双向链表的实现将是一个不错的选择。 With that, the content of each Node would be independent from the links between the nodes, enabling you to alter attributes of a Node without having to change the logic when creating the list itself.这样,每个节点的内容将独立于节点之间的链接,使您能够在创建列表本身时更改节点的属性而无需更改逻辑。

an example here: https://realpython.com/linked-lists-python/#how-to-use-doubly-linked-lists这里有一个例子: https://realpython.com/linked-lists-python/#how-to-use-doubly-linked-lists

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM