简体   繁体   English

python根据条件将字典列表分为两个列表

[英]python split list of dictionaries into two lists based on conditional

I'm trying to split a list of dictionaries into two lists based on a conditional being the type of the value in the dictionaries. 我试图根据条件是字典中值的类型将字典列表分为两个列表。 Is there anyway to do this in a one pass list comprehension? 无论如何,在一次通过列表理解中可以做到这一点吗?

Currently, I am doing this: 目前,我正在这样做:

nonvals = [{k: v for k, v in act.items() if type(v) != int} for act in actual]
vals = [{k: v for k, v in act.items() if type(v) == int} for act in actual]

Is there anyway I can return two lists based on the conditional in one list comprehension? 无论如何,我是否可以基于一个列表理解中的条件返回两个列表? If not what's a more pythonic way to split this list of dictionaries? 如果不是,还有什么更Python的方式来拆分此词典列表?

I am attempting to do the following as a final solution, but I feel like there is a lot of code repetition and extraneous looping that can be avoided - for reference both actual and expected are lists of dictionaries. 我尝试将以下内容作为最终解决方案,但我觉得可以避免很多代码重复和无关的循环- actualexpected参考是字典列表。 I would just like to get to the final solution in the fewest lines as possible. 我想以最少的行数得出最终解决方案。

I want to check if the non-int key, value pairs in expected are in the non-int key, value pairs in actual. 我想检查非int键,期望值对是否在非int键,实际值对中。 And in actual I just want to check if all the int key, value pairs are in the [-11, 11] range. 实际上,我只想检查所有int键,值对是否在[-11,11]范围内。


expected = [{'time': '12:34:22', 'place': 'LA', 'person': 'Mike', 'val1': 2, 'val2': 3, 'val3': 4},
            {'time': '11:45:15', 'place': 'SF', 'person': 'Emily', 'val1': 2, 'val2': 3, 'val3': 4}]

actual = [{'time': '12:34:22', 'place': 'LA', 'person': 'Mike', 'val1': 2, 'val2': 3, 'val3': 4},
          {'time': '11:45:15', 'place': 'SF', 'person': 'Emily', 'val1': 2, 'val2': 3, 'val3': 4},
          {'time': '21:19:57', 'place': 'LA', 'person': 'Leo', 'val1': 2, 'val2': 3, 'val3': 4},
          {'time': '15:43:11', 'place': 'LA', 'person': 'Marge', 'val1': 2, 'val2': 3, 'val3': 4}]

def check(expected, actual):

    nonvals = [{k: v for k, v in act.items() if type(v) != int} for act in actual]
    vals = [{k: v for k, v in act.items() if type(v) == int} for act in actual]


    for act in actual:
       for k, v in act.items():
           if v in vals and v not in range(-11, 11):
                 return False

    for exp in expected:
       if {k: v for k, v in exp.items() if type(v) != int} not in nonvals:
           return False

    return True

There is no general pythonic solution that will split a list based on some condition, let alone do the even more complicated job of splitting a dictionary based on some condition (like the type of the value matching a specific type). 没有通用的pythonic解决方案可以根据某种条件拆分列表,更不用说根据某种条件(如与特定类型匹配的值的类型)拆分字典的工作了。

Doing what you're doing is fairly readable and not a bad solution, but if you run into this problem more often, you could just write a function you can then apply to the dictionaries in the list: 做您的工作很容易阅读,而且不是一个不好的解决方案,但是如果您经常遇到此问题,则可以编写一个函数,然后将其应用于列表中的字典:

def pdict(d, condition):
    """
    Partition a dictionary based on some condition function
    :param d: a dict
    :param condition: a function with parameters k, v returning a bool for k: v in d
    :return: two dictionaries, with the contents of d, split according to condition
    """
    return {
        k: v for k, v in d.items() if condition(k, v)
    }, {
        k: v for k, v in d.items() if not condition(k, v)
    }  


original = [{'a': 1, 'b': 'two', 'c': 3}, {'a': 'one', 'b': 2}, {'a': 1, 'b': 2}]
int_result, nonint_result = [
    list(t) for t in zip(*[
        pdict(d, lambda k, v: isinstance(v, int)) for d in original
    ])   
]

print(int_result)
print(nonint_result)

This is clean and allows you to simply reuse partition_dict for similar cases. 这很干净,可以让您在类似情况下简单地重用partition_dict

The output produced by the example: 该示例产生的输出:

[{'a': 1, 'c': 3}, {'b': 2}, {'a': 1, 'b': 2}]
[{'b': 'two'}, {'a': 'one'}, {}]

A more simple example of (re)using pdict() : (重新)使用pdict()更简单示例:

d = {1: 42, 2: 33, 3: 5, 4: 10}
odd, even = pdict(d, lambda k, v: v % 2 == 1)
print(odd, even)

Output: 输出:

{2: 33, 3: 5} {1: 42, 4: 10}

A rewrite of pdict() that only loops once (as suggested by @blues), but is a bit wordier: pdict()重写仅循环一次(如@blues所建议),但有点冗长:

def pdict(d, condition):
    """
    Partition a dictionary based on some condition function
    :param d: a dict
    :param condition: a function with parameters k, v returning a bool for k: v in d
    :return: two dictionaries, with the contents of d, split according to condition
    """
    meets_condition = {}
    does_not_meet_condition = {}
    for k, v in d.items():
        if condition(k, v):
            meets_condition[k] = v
        else:
            does_not_meet_condition[k] = v
    return meets_condition, does_not_meet_condition

A disadvantage of this may be that for each element being added to the dictionaries, there may be some overhead in look-ups that the original example code can avoid in the dictionary comprehension. 这样的缺点可能是,对于每个添加到字典的元素,查找中可能会有一些开销,原始示例代码可以避免字典理解中的开销。 You could run performance tests to decide what is preferable, but the latter solution does avoid looping through the entire original dictionary twice. 您可以运行性能测试来确定最佳选择,但是后一种解决方案的确避免了遍历整个原始字典两次。 I think I'd prefer the first solution for anything that's not crazy large. 我想我希望第一个解决方案能够解决所有疯狂的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 python-将字典列表拆分为多个字典列表,而不进行分组 - python - split list of dictionaries into multiple lists of dictionaries, without grouping 将一个 Python 列表拆分成两个列表 - Split a Python List into two lists 根据 Python 中其中一个键/值对的唯一性,将字典列表拆分为多个列表 - Split a list of dictionaries into multiple lists based on uniqueness of one of the key/value pairs in Python 在Python中将两个列表转换为字典列表 - Converting two lists to a list of dictionaries in Python 将列表字典拆分为字典列表 - Split dictionary of lists into list of dictionaries 使用Python根据两个等长列表自动创建字典列表 - Automatically Creating List of Dictionaries Based Upon Two Lists of Equal Length with Python Python将两个长度不等的字典列表合并为一个基于键的列表 - Python combine two lists of dictionaries of unequal lengths into a single list based on a key 根据索引将Python列表拆分为多个列表 - Split Python list into several lists based on index 如何根据某些条件将字典列表拆分为单独的字典列表? - How can I split a list of dictionaries in separate lists of dictionaries based on some condition? 主要根据列表大小但其次根据条件在单独列表中拆分字典列表 - Split list of dictionaries in separate lists based primarily on list size but secondarily based on condition
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM