构建一个将列表转换为字典并根据条件分配键值的函数

Dav*_*vid 1 python dictionary list

我正在使用一个包含我感兴趣的三个不同类别的列表:整数,浮点数和字符串.我想将该列表转换为字典并将这三个类别中的每一个分配为一个键,然后将该列表的每个元素分配给适当的键值(例如,如果列表中的元素是字符串,那么它将被分配到"字符串"键的值.例如:

sample_list = [1.23, 34.34, 'abc', 'xyz', 22, 104]
Run Code Online (Sandbox Code Playgroud)

字典的结构应该是这样的:

new_dict = {"integers" : [list of all ints],
            "floats" : [list of all floats],
            "strings" : [list of all strings],
            }
Run Code Online (Sandbox Code Playgroud)

从上面的示例列表中,输出将如下所示:

list_to_dict = {'float': [1.23, 34.34], 
                'integer', [22, 104], 
                'string', ['abc', 'xyz']
                }
Run Code Online (Sandbox Code Playgroud)

我正在使用dict()和zip()将字典转换为列表,但我不确定如何构建条件以将原始列表的每个元素放入正确的键值对.这是我到目前为止所拥有的:

keys = ['integers', 'floats', 'strings']
values = [1.23, 34.34, 'abc', 'xyz', 22, 104]
mixed_dictionary = dict(zip(keys,values))
Run Code Online (Sandbox Code Playgroud)

这是正确的方法还是我应该采取不同的做法?如果这是正确的方法,我如何添加条件以将所有列表元素放入适当的键值?我尝试使用for循环和.append(),但都没有工作.

cs9*_*s95 8

您希望根据某些谓词对数据进行分组.基本步骤是:

  1. 确定该项目属于哪个组
  2. 将项目放入该组的相应"桶"中.

有很多方法可以实现这一目标.有些比其他更直接.

选项1
这是一个很好的用例itertools.groupby.这里的谓词是type一个元素.

但请注意,如果您的数据未按类型排序,则无法使用此功能.这可能会导致问题,因此请先对数据进行预排序:

sample_list.sort(key=lambda x: id(type(x)))
Run Code Online (Sandbox Code Playgroud)

现在,调用groupby并解压缩每个组作为dict理解中的列表:

from itertools import groupby
{i.__name__ : list(g) for i, g in groupby(sample_list, key=type)}
Run Code Online (Sandbox Code Playgroud)

{
    "float": [
        1.23,
        34.34
    ],
    "str": [
        "abc",
        "xyz"
    ],
    "int": [
        22,
        104
    ]
}
Run Code Online (Sandbox Code Playgroud)

选项2
下面是使用另一种方法groupbypandasAPI.这不需要预先分类步骤.

import pandas as pd

s = pd.Series(sample_list)   
s.groupby(s.map(lambda x: type(x).__name__)).apply(list).to_dict()
Run Code Online (Sandbox Code Playgroud)

{
    "float": [
        1.23,
        34.34
    ],
    "str": [
        "abc",
        "xyz"
    ],
    "int": [
        22,
        104
    ]
}
Run Code Online (Sandbox Code Playgroud)

选项3
这是使用字典的第三个选项setdefault(类似于a的其他答案defaultdict):

gps = {}
for s in sample_list:
    gps.setdefault(type(s).__name__, []).append(s)
Run Code Online (Sandbox Code Playgroud)

gps

{
    "float": [
        1.23,
        34.34
    ],
    "str": [
        "abc",
        "xyz"
    ],
    "int": [
        22,
        104
    ]
}
Run Code Online (Sandbox Code Playgroud)

然而,如果我们谈论效率,defaultdict那么另一个答案中的方法与dict+ 相比稍微有效setdefault.


Chi*_*xus 5

您可以使用defaultdictfrom collectionsmodule:

from collections import defaultdict
sample_list = [1.23, 34.34, 'abc', 'xyz', 22, 104]
final = defaultdict(list)
for elm in sample_list:
    final[type(elm).__name__].append(elm)

print(final)
Run Code Online (Sandbox Code Playgroud)

输出:

defaultdict(<type 'list'>, {'int': [22, 104], 'float': [1.23, 34.34], 'str': ['abc', 'xyz']})
Run Code Online (Sandbox Code Playgroud)

你可以转换final为常规dict:

print(dict(final))
{'int': [22, 104], 'float': [1.23, 34.34], 'str': ['abc', 'xyz']}
Run Code Online (Sandbox Code Playgroud)