[英]merging two dictionaries of lists with the same keys in python
我的問題:
我正在嘗試將兩個列表詞典合並到一個新詞典中,為每個鍵交替2個原始列表的元素,以創建該鍵的新列表。
例如,如果我有兩個詞典:
strings = {'S1' : ["string0", "string1", "string2"], 'S2' : ["string0", "string1"]}
Ns = {'S1' : ["N0", "N1"], 'S2' : ["N0"]}
我想合並這兩個詞典,以便最終字典看起來像:
strings_and_Ns = {'S1': ["string0", "N0", "string1", "N1", "string2"], 'S2': ["string0", "N0", "string1"]}
或者更好的是,讓列表中的字符串為每個鍵連接在一起,例如:
strings_and_Ns = {'S1': ["string0N0string1N1string2"], 'S2': ["string0N0string1"]}
(我正在嘗試將DNA序列片段連接在一起。)
到目前為止我嘗試過的:
壓縮
for S in Ns:
newsequence = [zip(strings[S], Ns[S])]
newsequence_joined = ''.join(str(newsequence))
strings_and_Ns[species] = newsequence_joined
這不會將序列連接成一個字符串,並且字符串的順序仍然不正確。
使用defaultdict
from collections import defaultdict
strings_and_Ns = defaultdict(list)
for S in (strings, Ns):
for key, value in S.iteritems():
strings_and_Ns[key].append(value)
這個字符串的順序也是不正確的......
以某種方式移動每個鍵的列表......
for S in strings:
list = strings[S]
L = len(list)
for i in range(L):
strings_and_Ns[S] = strings_and_Ns[S] + strings[S][i] + strings[S][i]
strings_and_Ns = {}
for k,v in strings.items():
pairs = zip(v, Ns[k] + ['']) # add empty to avoid need for zip_longest()
flat = (item for sub in pairs for item in sub)
strings_and_Ns[k] = ''.join(flat)
flat
是根據這里接受的答案構建的: 在Python中列出列表中的平面列表
要交替x
, y
迭代插入default
值的default
值:
from itertools import izip_longest
def alternate(x, y, default):
return (item for pair in izip_longest(x, y, default) for item in pair)
a = {'S1' : ["string0", "string1", "string2"], 'S2' : ["string0", "string1"]}
b = {'S1' : ["N0", "N1"], 'S2' : ["N0"]}
assert a.keys() == b.keys()
merged = {k: ''.join(alternate(a[k], b[k], '')) for k in a}
print(merged)
{'S2': 'string0N0string1', 'S1': 'string0N0string1N1string2'}
itertools.izip_longest將處理不均勻的長度列表,然后使用str.join
連接成一個單獨的字符串。
strings = {'S1' : ["string0", "string1", "string2"], 'S2' : ["string0", "string1"]}
Ns = {'S1' : ["N0", "N1"], 'S2' : ["N0"]}
from itertools import izip_longest as iz
strings_and_Ns = {k:["".join([a+b for a, b in iz(strings[k],v,fillvalue="")])] for k,v in Ns.items()}
print(strings_and_Ns)
{'S2': ['string0N0string1'], 'S1': ['string0N0string1N1string2']}
這與以下相同:
strings_and_Ns = {}
for k, v in Ns.items():
strings_and_Ns[k] = ["".join([a + b for a, b in iz(strings[k], v, fillvalue="")])]
使用izip_longest
意味着無論哪個dict的值包含更多元素,代碼都將起作用。
與發布的其他解決方案類似,但我會將其中的一部分移到一個函數中
import itertools
def alternate(*iters, **kwargs):
return itertools.chain(*itertools.izip_longest(*iters, **kwargs))
result = {k: ''.join(alternate(strings[k], Ns[k] + [''])) for k in Ns}
print result
得到:
{'S2': 'string0N0string1', 'S1': 'string0N0string1N1string2'}
alternate
功能來自https://stackoverflow.com/a/2017923/66349 。 它將iterables作為參數並連續地將每個項鏈接在一起(使用izip_longest
作為Padraic Cunningham所做的)。
您可以指定fillvalue=''
來處理不同的長度列表,或者只是手動填充較短的列表,如上所述(假設Ns
總是比strings
短一個)。
如果你有一個不支持dict理解的舊python版本,你可以使用它
result = dict((k, ''.join(alternate(strings[k], Ns[k] + ['']))) for k in Ns)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.