【问题标题】:How to do Python one liner to create a dict from result set如何用 Python 单线从结果集中创建一个字典
【发布时间】:2020-07-10 17:20:59
【问题描述】:

我有什么:

d1=[{'type':'fruit','name':'apple'},{'type':'fruit','name':'orange'},{'type':'vehicle','name':'car'},{'type':'vehicle','name':'bike'}]

我做了什么:

res=[{i['type']:i['name']} for i in d1]

我收到了什么:

res=>[{'fruit': 'apple'}, {'fruit': 'orange'}, {'vehicle': 'car'}, {'vehicle': 'bike'}]

但我需要什么:

res=>{'fruit': ['apple','orange'], 'vehicle': ['car','bike']}

如何做到这一点?提前谢谢

更新 这将更具可读性。但我想要一个班轮!

u={}
for i in d1:
    if u.get(i['type']):
        u[i['type']].append(i['name'])
    else:
        u[i['type']]=[i['name']]

【问题讨论】:

  • 我强烈建议避免使用单行代码以提高可读性。但是,如果您真的需要它,@deceze 的回答非常好。

标签: python python-3.x list-comprehension


【解决方案1】:

至于单线,必须是这样的:

from itertools import groupby
from operator import itemgetter

res = {k: list(map(itemgetter('name'), v)) for k, v in groupby(sorted(d1, key=itemgetter('type')), itemgetter('type'))}

我认为这很复杂,但是你去吧……

【讨论】:

  • 很好,我正在尝试类似的东西,但不知道 itemgetter(学到了一些东西!)。这实际上看起来比你经历它时更糟糕,但我同意除了 OP 之外的每个人的普遍看法,即一个班轮不是真正有效也不可读。
【解决方案2】:

你可以试试这个oneliner:

d1=[{'type':'vehicle','name':'car'},{'type':'fruit','name':'apple'},{'type':'fruit','name':'orange'},{'type':'vehicle','name':'bike'}]

res = {
    k: [d.get('name') for d in d1 if k in d.values()]
    for k in set(list(map(lambda x: x['type'],d1)))
}

print(res)

或者你可以试试这个“双线”:

d1=[{'type':'fruit','name':'apple'},{'type':'fruit','name':'orange'},{'type':'vehicle','name':'car'},{'type':'vehicle','name':'bike'}]

temp=[{d['type']:d['name']} for d in d1]
res = {k: list(filter(None,[d.get(k) for d in temp]))
    for k in set().union(*temp)
}
print(res)

第二个解决方案基于Alex Hall's answer

输出:

{'vehicle': ['car', 'bike'], 'fruit': ['apple', 'orange']}

【讨论】:

    【解决方案3】:

    我不想在这里使用 oneliner。可能是这样的

    x = {}
    for item in d1:
        x.setdefault(item['type'], []).append(item['name'])
    

    对我来说,它更具可读性

    如果你真的坚持使用oneliner,你可以这样做。但这会产生像[None, None] 这样的空列表,将被丢弃

    x = {}
    [x.setdefault(item['type'], []).append(item['name']) for item in d1]
    

    【讨论】:

    • 可读代码意味着我可以这样做,u={} for i in d1: if u.get(i['type']): u[i['t​​ype']].append (i['name']) else: u[i['t​​ype']]=[i['name']] 但我想要一个高效的班轮
    • @Vanjith 您可以将if..else 替换为演示的setdefault,这样会更简单。
    • 推荐的网友是very anti-Pythonic
    猜你喜欢
    • 1970-01-01
    • 2019-10-11
    • 2015-01-30
    • 2018-04-30
    • 2022-11-17
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多