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

时间:2018-02-03 01:59:56

标签: python list dictionary

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

sample_list = [1.23, 34.34, 'abc', 'xyz', 22, 104]

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

new_dict = {"integers" : [list of all ints],
            "floats" : [list of all floats],
            "strings" : [list of all strings],
            }

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

list_to_dict = {'float': [1.23, 34.34], 
                'integer', [22, 104], 
                'string', ['abc', 'xyz']
                }

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

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

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

2 个答案:

答案 0 :(得分:8)

您希望根据某些谓词分组您的数据。基本步骤是:

  1. 确定该项目属于哪个组
  2. 将该项目放入该组的相应“桶”中。
  3. 有很多方法可以实现这一目标。有些比其他更直接。

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

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

    sample_list.sort(key=lambda x: id(type(x)))
    

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

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

    {
        "float": [
            1.23,
            34.34
        ],
        "str": [
            "abc",
            "xyz"
        ],
        "int": [
            22,
            104
        ]
    }
    

    选项2
    以下是使用pandas API中的groupby的替代方法。这不需要预先排序步骤。

    import pandas as pd
    
    s = pd.Series(sample_list)   
    s.groupby(s.map(lambda x: type(x).__name__)).apply(list).to_dict()
    

    {
        "float": [
            1.23,
            34.34
        ],
        "str": [
            "abc",
            "xyz"
        ],
        "int": [
            22,
            104
        ]
    }
    

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

    gps = {}
    for s in sample_list:
        gps.setdefault(type(s).__name__, []).append(s)
    

    gps
    
    {
        "float": [
            1.23,
            34.34
        ],
        "str": [
            "abc",
            "xyz"
        ],
        "int": [
            22,
            104
        ]
    }
    

    但是,如果我们谈论效率,那么与defaultdict + dict相比,其他答案中的setdefault方法效率稍高。

答案 1 :(得分:5)

您可以使用defaultdict模块中的collections

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)

输出:

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

您可以将final转换为常规dict

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