Python 如何拆分并转换为字典和交换键值

Python 如何拆分并转换为字典和交换键值,python,Python,我有名单 [“德国+A”、“法国+A”、“英国+B”、“德国+A”] 我需要转换字典 我需要和你分开+ 转换为字典并交换值 如果存在这些值,则无需进行处理 应为字典{“A”:[“德国”、“法国”],“B”:[“英国”]} 代码如下,我仅以字典的形式获得输出,需要插入一个条件,如果值存在,则无需处理 l = ["Germany + A", "France + A", "England + B", "Germany + A&

我有名单

[“德国+A”、“法国+A”、“英国+B”、“德国+A”]

  • 我需要转换字典
  • 我需要和你分开+
  • 转换为字典并交换值
  • 如果存在这些值,则无需进行处理
应为字典
{“A”:[“德国”、“法国”],“B”:[“英国”]}

代码如下,我仅以字典的形式获得输出,需要插入一个条件
,如果值存在,则无需处理

l = ["Germany + A", "France + A",  "England + B", "Germany + A"  ]
m = []
for i in l:
    m.append(i.split('+'))
for k,v in m:
    n ={k:v}
    print({v: k for k, v in n.items()} 
l=[“德国+A”、“法国+A”、“英国+B”、“德国+A”、“尼日利亚”]
m={}
对于l中的s:
尝试:
#如果没有“+”,则会引发ValueError异常
#这里剩下的处理将被跳过
国家,类别=s.split(“+”,2)
country=country.strip()
category=category.strip()
foo=m.setdefault(类别,[])
如果国家不在foo中:
foo.append(国家)
除ValueError为e外:
#在这里,如果抛出ValueError,代码将继续
#“通过”意味着什么也不做
通过
打印(m)
作为旁注-使用有意义的名称,而不是神秘的单字符名称

作为使用
dict.setdefault()
的替代方法,可以使用默认值为
list
collections.defaultdict
,或者如果顺序不重要-
set

编辑:比较使用
dict.setdefault
collections.defaultdict(列表)

输出

0.2819225169987476
0.3298255940026138

至少对于小样本数据
setdefault
要快一点。

我认为在这里选择可读的解决方案是最好的

循环浏览列表
l
,然后在
“+”
上进行拆分

然后,在第一次遇到国家名称时,将其附加到相应的键

注意使用
collections.defaultdict
将字典初始化为列表的dict

import collections

l = ["Germany + A", "France + A", "England + B", "Germany + A"]

d = collections.defaultdict(list)

for i in l:
    k, v = i.split(' + ')
    if k not in d[v]:
        d[v].append(k)

print(dict(d))
这将提供以下输出:

{'A': ['Germany', 'France'], 'B': ['England']}
如果您想坚持原来的方法,可以再次使用
'+'
进行拆分,并使用列表理解将结果放入列表中:

m = [i.split(' + ') for i in l]
然后,您将像这样循环通过
m

for k, v in m:
    if k not in d[v]:
        d[v].append(k)
如果您想要中间
m
列表,这非常有用。

l=[“德国+A”、“法国+A”、“英国+B”、“德国+A”]
m=[]
DICT={}
对于l中的i:
m、 追加(i.split(+'))
对于k,v,m:
如果在DICT中为v:
如果k不在DICT[v]中:
DICT[v].附加(k)
其他:
DICT[v]=[]
DICT[v].附加(k)
打印(DICT)
实现这一点的另一种方法 有一个很棒的Python库,名为,它还可以做一些出色的工作,并为您提供一些灵活性:

#输入
L=[“德国+A”、“法国+A”、“英国+B”、“德国+A”]
#预处理
L=[L中L的L.split('+')]
作为pd进口熊猫
df=pd.DataFrame(L,columns=['country','type'])#给这些列起一些名字
查看df中的内容:

>>> df
   country type
0  Germany    A
1   France    A
2  England    B
3  Germany    A
结果是:

>>> grouped
{'A': ['Germany', 'France'], 'B': ['England']}

就是这样。

这不是一个有效的解决方案,但有多种解决方案

将多个问题组合成一个问题

from itertools import groupby

s=["Germany + A", "France + A",  "England + B", "Germany + A"  ]

m=[i.strip(' ').split('+') for i in s]
[['Germany ', ' A'], ['France ', ' A'], ['England ', ' B'], ['Germany ', ' A']]

#Grouping based on alphabets 'A' , B
new=[list(g) for k, g in groupby(sorted(m,reverse=True), lambda x:x[1])]
[[['Germany ', ' A'], ['Germany ', ' A'], ['France ', ' A']],
[['England ', ' B']]]


#swapping alphabet and Countries position
new=[item[::-1] for sublist in new for item in sublist ]
[[' A', 'Germany '], [' A', 'Germany '], [' A', 'France '], [' B', 'England       ']]


dct = dict((key, tuple(v for (k, v) in pairs)) 
           for (key, pairs) in itertools.groupby(new, lambda pair: pair[0]))
{' A': ('Germany ', 'Germany ', 'France '), ' B': ('England ',)}


{k:list(set(v)) for k,v in dct.items()}

@这就回答了这个问题。我不明白为什么要投否决票。@如果你认为这很复杂,我不知道该说什么。这很简单,你能查一下上面的吗scenario@sim编辑完成,请查看新答案。@sim这是Python的“gotcha”。您希望
foo
m[category]
是两个不同的列表,对吗?但是
foo
实际上是指向
m[category]
的指针。您应该使用
set
而不是
list
,来启动defaultdict,然后使用
d[v]。添加
而不是
d[v]。追加。如果k尚未出现,则可以删除检查。+1用于使用defaultdict,这是作业的正确工具。我不知道其他答案为什么使用
.setdefault
manually@programmer“应该”在这里是值得怀疑的。目前尚不清楚这是否合适。我确实想过使用
集合
,并且打算这样做,但那将是集合的记录而不是列表的记录,因此我坚持使用列表代替。我想这两种方法都可以(这是一个简单的改变)。是的,除非OP想要用数百万个字符串来实现这一点,否则它不会有任何区别。解释,纯代码回答…你能再检查一个场景吗,l=[“德国+a”,“法国+a”,“英国+B”,“德国+a”,“尼日利亚”],在这个输出中也是一样的,因为“尼日利亚”后面没有“+”向上投票,你能检查一下上面的场景吗
# Then, drop duplicate records:
df.drop_duplicates(['country', 'type'], inplace=True)

# Group by type, convert to list for each record and dump to a dict in one shot
grouped = df.groupby('type').apply(lambda x: x['country'].tolist()).to_dict()
>>> grouped
{'A': ['Germany', 'France'], 'B': ['England']}
from itertools import groupby

s=["Germany + A", "France + A",  "England + B", "Germany + A"  ]

m=[i.strip(' ').split('+') for i in s]
[['Germany ', ' A'], ['France ', ' A'], ['England ', ' B'], ['Germany ', ' A']]

#Grouping based on alphabets 'A' , B
new=[list(g) for k, g in groupby(sorted(m,reverse=True), lambda x:x[1])]
[[['Germany ', ' A'], ['Germany ', ' A'], ['France ', ' A']],
[['England ', ' B']]]


#swapping alphabet and Countries position
new=[item[::-1] for sublist in new for item in sublist ]
[[' A', 'Germany '], [' A', 'Germany '], [' A', 'France '], [' B', 'England       ']]


dct = dict((key, tuple(v for (k, v) in pairs)) 
           for (key, pairs) in itertools.groupby(new, lambda pair: pair[0]))
{' A': ('Germany ', 'Germany ', 'France '), ' B': ('England ',)}


{k:list(set(v)) for k,v in dct.items()}