Python 如何在不使用嵌套for循环的情况下将两个列表合并到字典中
我有两份清单:Python 如何在不使用嵌套for循环的情况下将两个列表合并到字典中,python,list,dictionary,Python,List,Dictionary,我有两份清单: a = [0, 0, 0, 1, 1, 1, 1, 1, .... 99999] b = [24, 53, 88, 32, 45, 24, 88, 53, ...... 1] 我想将这两个列表合并到字典中,如下所示: { 0: [24, 53, 88], 1: [32, 45, 24, 88, 53], ...... 99999: [1] } 一个解决方案可能是使用for循环,这看起来并不美观,例如: d = {} unique_a =
a = [0, 0, 0, 1, 1, 1, 1, 1, .... 99999]
b = [24, 53, 88, 32, 45, 24, 88, 53, ...... 1]
我想将这两个列表合并到字典中,如下所示:
{
0: [24, 53, 88],
1: [32, 45, 24, 88, 53],
......
99999: [1]
}
一个解决方案可能是使用for
循环,这看起来并不美观,例如:
d = {}
unique_a = list(set(list_a))
for i in range(len(list_a)):
if list_a[i] in d.keys:
d[list_a[i]].append(list_b[i])
else:
d[list_a] = [list_b[i]]
虽然这确实有效,但它效率低下,而且在列表非常大的情况下需要花费太多时间。我想知道构造这样一本词典的更优雅的方法
提前谢谢 您可以使用:
输出:
{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}
也许我没抓住重点,但至少我会尽力帮忙。如果你必须列出清单,并想把它们放在口述中,请执行以下操作
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
lists = [a, b] # or directly -> lists = [ [1, 2, 3, 4], [5, 6, 7, 8] ]
new_dict = {}
for idx, sublist in enumerate([a, b]): # or enumerate(lists)
new_dict[idx] = sublist
希望它有助于替代解决方案:
import itertools
a = [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3]
b = [24, 53, 88, 32, 45, 24, 88, 53, 11, 22, 33, 44, 55, 66, 77]
result = { k: [i[1] for i in g]
for k,g in itertools.groupby(sorted(zip(a, b)), key=lambda x:x[0]) }
print(result)
输出:
{0: [24, 53, 88], 1: [24, 32, 45, 53, 88], 2: [11, 22, 33, 44, 55, 66], 3: [77]}
你可以通过听写理解来做到这一点:
list_a = [0, 0, 0, 1, 1, 1, 1, 1]
list_b = [24, 53, 88, 32, 45, 24, 88, 53]
my_dict = {key: [] for key in set(a)} # my_dict = {0: [], 1: []}
for a, b in zip(list_a, list_b):
my_dict[a].append(b)
# {0: [24, 53, 88], 1: [32, 45, 24, 88, 53]}
d={k:[] for k in l}
for x,y in zip(l,l2):
d[x].append(y)
奇怪的是,您似乎无法使用dict.fromkeys(set(list_a),[])实现这一点,因为这会将所有键的值设置为相同的空数组:
my_dict = dict.fromkeys(set(list_a), []) # my_dict = {0: [], 1: []}
my_dict[0].append(1) # my_dict = {0: [1], 1: [1]}
pandas
解决方案:
import itertools
a = [0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3]
b = [24, 53, 88, 32, 45, 24, 88, 53, 11, 22, 33, 44, 55, 66, 77]
result = { k: [i[1] for i in g]
for k,g in itertools.groupby(sorted(zip(a, b)), key=lambda x:x[0]) }
print(result)
设置:
解决方案:
演练:
pd.DataFrame
,a
称为Group
,b
称为Value
df.groupby('Group')
基于a创建组
.Value.apply(list)
获取每个组的值,并将其强制转换到list
.to_dict()
将生成的DataFrame
转换为dict
a = sorted(np.random.randint(0, 100000, 1000000).tolist())
b = pd.np.random.randint(0, 100, len(a)).tolist()
df = pd.DataFrame(columns=['Group', 'Value'], data=list(zip(a, b)))
>>> df.shape
Out[]: (1000000, 2)
%timeit df.groupby('Group').Value.apply(list).to_dict()
4.13 s ± 9.29 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
但老实说,它的效率可能不如@RomanPerekhrest建议的
itertools.groupby
,或者@Ajax1234建议的defaultdict
。没有花哨的结构,只是一本普通的ol'字典
d = {}
for x, y in zip(a, b):
d.setdefault(x, []).append(y)
或者预先理解字典,因为所有键都有空列表的值,所以通过两个列表的
zip
进行迭代,然后将第二个列表的值添加到字典的键中,命名第一个列表的值,不需要try-except子句(或if语句),以查看键是否存在,由于事先的词典理解:
list_a = [0, 0, 0, 1, 1, 1, 1, 1]
list_b = [24, 53, 88, 32, 45, 24, 88, 53]
my_dict = {key: [] for key in set(a)} # my_dict = {0: [], 1: []}
for a, b in zip(list_a, list_b):
my_dict[a].append(b)
# {0: [24, 53, 88], 1: [32, 45, 24, 88, 53]}
d={k:[] for k in l}
for x,y in zip(l,l2):
d[x].append(y)
现在:
是:
当然,我已经弄明白了你的代码是做什么的,但是用那种风格写的,它不是很明显。对于Python新手来说,我认为他们可能会发现您的代码很难理解,然后因为它而忽略(或不考虑)您的解决方案。只是一个建议,由你决定。我可以建议不要在一行中写
结果吗?是否可以将groupby
的结果作为一个单独的变量提取出来?这行太长了……这似乎比另一个答案更糟,因为你需要排序,而另一个答案没有排序,所以你的答案需要做额外的工作。@Daenyth,你的信息一点也不新。解决方案一开始就被标记为“可选”方式。如果已订购了list\u a
,则可以删除n log n
排序,并且lambda会增加不必要的开销,itemgetter始终是更好的选择<代码>{k:[i for u,i in g]for k,g in groupby(zip(a,b),key=itemgetter(0))
这是一个如何嵌套的for循环?DYM如果d.keys中的list_a[i]和d[list_a[i]=[list_b[i]
?请准确地发布您尝试过的代码,最好使用复制+粘贴(如果您的平台上提供)。如果提供的答案之一对您有效,请将其标记为已接受。它使将来遇到你的问题的人更容易知道什么有用。@TobySpeight如果表示如果列表a[i]
已经是字典中的一个键,那么将列表b[i]
添加到字典的列表a[i]
下,而否则表示如果不是,则添加列表b[i]到新键
list_a[i]`as list。希望能有帮助。@BigD,我想这就是你想写的(正如我建议的)list_u[a]根本没有意义,d[list_u[a]=
。我建议您修复这些错误。这与OP想要的还不太接近a
包含b
中值的键(有些键是重复的),并且根本不使用索引。您只需使用列表中的索引创建{0:a,1:b}
。实际上,使用defaultdict
在这里是过分的。请参阅wheredict.setdefault
可以以最小的开销处理相同的事情。@cᴏʟᴅsᴘᴇᴇᴅ <代码>d[a].append(b)
比d.setdefault(x,[])干净得多。append(y)
以额外导入和更重的结构为代价;-)列表是可变的,您将一个对象/列表传递给fromkeys,以便共享对单个列表/对象的引用,这与a=[]
然后d={1:a,2:a,3:a}
相同my_dict=dict.fromkeys(set(list_a),tuple());我的dict[0]+=(1,)
将显示{0:(1,),1:(),9999:()}
,但会增加使用每个+=
创建新对象/元组的开销。
print(d)
{0: [24, 53, 88], 1: [32, 45, 24, 88, 53], 9999: [1]}