如何在循环内向字典中的键添加值?

5

我有以下列表:

x=['a','3','4','b','1','2','c','4','5']

如何创建以下字典:
b = {'a':[3,4],'b':[1,2],'c':[4,5]}

我尝试了以下方法:
Category = defaultdict(int)
for i in a:
    if Varius.is_number(i)==False:
        Category[i]=[]
        keys.append(i)
    else:
        Category[keys(i)] = i

密钥已创建,但在插入值时遇到问题。(is_number是一个函数,用于检查列表的值是数字还是字符串)。离开MATLAB的第一天。Python的第一天。

6个回答

4

这里有一个实际使用defaultdict功能的例子,它与普通的dict相比提供了更多的特性:

from collections import defaultdict

x=['a','3','4','b','1','2','c','4','5']

key='<unknown>' # needed if the first value of x is a number
category = defaultdict(list)  # defaultdict with list
for i in x:
    if i.isalpha():
        key = i;
    else:
        category[key].append(i) # no need to initialize with an empty list

print category

此外:您应该使用小写名称来表示类实例。大写名称通常保留用于表示类。请阅读PEP 8以获取样式指南。


4

如果您列表 x 中的键/值条目间距相等,这里有一种构建字典的替代方法。它使用了Python内置的一些特性和函数:

>>> keys = x[::3]
>>> values = [map(int, pair) for pair in zip(x[1::3], x[2::3])]
>>> dict(zip(keys, values))
{'a': [3, 4], 'b': [1, 2], 'c': [4, 5]}

这里使用了以下方法:

  • 使用列表切片从x创建新的列表:x[start:stop:step]
  • zip将两个列表组合成元组的列表,包含每个列表的第n个元素
  • map(int, pair)将数字字符串元组转换为整数列表
  • values采用列表推导式构造 - 将map函数应用于每对
  • dict将一对键/值列表转换为字典

1
这仅适用于原帖中相关条目均匀分布的情况。我会在答案中明确说明。 - Alex Riley

2
你可以使用 itertools.groupby
>>> from itertools import groupby
>>> l=[list(g) for k,g in groupby(x,lambda x : x.isalpha())]
>>> p=[l[i:i+2] for i in range(0,len(l),2)]
>>> {i[0]:map(int,j) for i,j in p}
{'a': [3, 4], 'c': [4, 5], 'b': [1, 2]}

我认为原帖的意思不是想要1或3作为键。 - Kevin
@Kevin 是的,我漏掉了一些东西,我会更新的,感谢您提醒。 - Mazdak

1
假设您的列表(x)中在第一个位置有一个密钥,并且字母后面会有一个数字:
from collections import defaultdict

x=['a','3','4','b','1','2','c','4','5']

key = x[0]
Category = defaultdict(int)
for i in x:
    if i.isalpha():
        key = i;
    else:
        Category[key].append(i)

print Category

如果您使用空列表初始化每个字典值,则无需使用“defaultdict”。 - PeterE

1

使用 itertools.groupby 和一些迭代器技巧:

>>> from itertools import groupby  
>>> it = (next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha))
>>> {k: next(it) for k in it}
{'a': [3, 4], 'c': [4, 5], 'b': [1, 2]}

这里第一个迭代器将会产生类似如下的结果:

>>> [next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha)]
['a', [3, 4], 'b', [1, 2], 'c', [4, 5]]

现在,由于这个迭代器将交替地生成键值对,所以我们可以循环遍历该迭代器并从中获取下一个项目(即值),使用next()
>>> it = (next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha))
>>> for k in it:                                                            
    print k,'-->' ,next(it)
...     
a --> [3, 4]
b --> [1, 2]
c --> [4, 5]

还有一种使用zip来消费这个迭代器的方法,但是在我看来它有点难以理解:

>>> it = (next(g) if k else map(int, g) for k, g in groupby(x, str.isalpha))
>>> dict(zip(*[it]*2))
{'a': [3, 4], 'c': [4, 5], 'b': [1, 2]}

0

使用仅 dictlist 的简单解决方案:

>>> category = {}
>>> for i in x:
...     if i.isalpha():
...         items = category[i] = []
...     elif category:
...         items.append(i)
... 
>>> print(category)
{'c': ['4', '5'], 'a': ['3', '4'], 'b': ['1', '2']}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接