【问题标题】:Replace values in a dictionary with the values from the list用列表中的值替换字典中的值
【发布时间】:2013-06-03 19:17:30
【问题描述】:

我正在尝试用列表中的值替换字典中的值。

我有:

list1 = ['10 2', '8 6']

d = {'0.25': ['11 3', '9 1'], '0.75': ['3 9'], '0.5': ['10 12', '6 0'], '0.0': ['1 8']}

我希望我的字典看起来像:

dFinal = {'0.25': ['10 2'], '0.75': ['3 9'], '0.5': ['8 6'], '0.0': ['1 8']}

一般来说,如果我的键的值是包含两个项目的列表,我想用 list1 中的特定项目替换该值。我希望该方法适用于具有任意数量项目的 list1,这似乎是我的问题。

到目前为止,我得到了:

for key in d:
    if len(d[key]) == 2:
        d[key] = list1[0]

但它只用一个值替换所有内容,我想避免调用静态索引,因为我的 list1 的长度可能会有所不同......我错过了某种循环吗?

干杯!

【问题讨论】:

  • 为什么['11 3', '9 1']['10 2']['10 12', '6 0']['8 6']取代。来自list1 的项目作为替代品的一般规则是什么?
  • 请注意,字典不能保证保留键的顺序。
  • 对,字典中的键没有排序。您希望在哪个订单中替换它们?
  • 规则是 list1 中的第一项将 value 的第一个实例替换为两项。我不知道顺序可能会改变...... list1 中的项目是平均值:对于“11 3”和“9 1”,平均值是“10 2”
  • @kate88 字典中没有“第一个值”这样的东西。您希望如何订购您的钥匙?按价值?按插入时间?

标签: python list dictionary


【解决方案1】:

您可以添加一个简单的计数器(一个新变量)。

i = 0
for key in d:
    #check if we're not out of bounds
    if i >= len(list1):
        break
    if len(d[key]) == 2:
        d[key] = [list1[i]]
        i+=1

【讨论】:

  • @MikeMüller 任何答案的重点都不是工作代码,而是工作想法。
  • @MikeMüller 大多数语言 i++i += 1 的意思相同,python 似乎有点不同
  • @Martyn 是的,是i += 1
  • @kirelagin 新用户尝试一些本应是不起作用的解决方案的代码非常令人沮丧。他们认为他们做错了什么。如果它看起来像 Python,它应该可以运行。否则使用伪代码并使其看起来像伪代码。
【解决方案2】:
list1 = ['10 2', '8 6']
d = {'0.25': ['11 3', '9 1'], '0.75': ['3 9'], '0.5': ['10 12', '6 0'], '0.0': ['1 8']}
iter_list = iter(list1)
for key, value in d.items():
    if len(value) == 2:
        try:
            d[key] = [next(iter_list)]
        except StopIteration:
            break

结果:

{'0.0': ['1 8'], '0.25': ['10 2'], '0.5': ['8 6'], '0.75': ['3 9']}

【讨论】:

    【解决方案3】:

    这应该可以解决问题:

    replace = [x for x in d if len(d[x]) == 2]
    for (i, x) in enumerate(replace):
       d[x] = [list1[i]]
    

    但是,我认为您需要非常小心,因为字典不是有序列表,因此如果要正确映射 list1 中的元素,您需要检查 Python 是否没有改组字典。上面的代码可以很好地与提供的示例配合使用,但任何解决方案的稳健性都将取决于您在其他地方使用字典(和list1)做什么。

    抱歉,我有点挑剔,但我在后台使用 Python 洗牌字典时遇到了问题,并且之前它破坏了我的算法。

    【讨论】:

    • 您应该补充一点,这仅在 list1 的元素数量至少与字典中包含两个元素的列表的值一样多的情况下才有效。
    • 同意,我只是假设问题会是这种情况,但如果不是,则会导致错误。很容易添加子句if i == len(list1): break 来涵盖这一点。
    【解决方案4】:

    您可以使用zip()

    >>> list1 = ['10 2', '8 6']
    >>> for x, y in zip(list1,d.items()):
    ...     d[y[0]] = [x]
    ... 
    >>> print d
    {'0.25': ['10 2'], '0.5': ['8 6'], '0.75': ['3 9'], '0.0': ['1 8']}
    

    解释:

    zip(list1,d.items())
    

    返回:

    [('10 2', ('0.25', ['10 2'])), ('8 6', ('0.5', ['8 6']))]
    

    它只获取长度为 2 的键的值,就像 zip() 所做的那样。然后我遍历列表,更改字典中与zip(list1,d.items()) 中的第一个值相对应的键的值。

    【讨论】:

    • 我认为这并不完全正确:在这种情况下,zip 正在返回您想要的内容,因为 Python 正在重新排序字典,使得长度为 2 的键都在开头(不是确定为什么),所以他们被zip 带走了。如果 list1 的长度大于长度为 2 的项目数,zip 也会返回长度为 1 的项目。
    【解决方案5】:

    使用过滤器、压缩和更新功能,您可以以一种更简单的方式实现此目的:

    list1 = ['10 2', '8 6']
    
    d = {'0.25': ['11 3', '9 1'], '0.75': ['3 9'], '0.5': ['10 12', '6 0'], '0.0': ['1 8']}
    
    print d
    target_keys = filter(lambda x: len(d[x]) == 2, d.keys())
    new_list = zip(target_keys, list1)
    new_dict = dict(new_list)
    d.update(new_dict)
    print d
    

    zip 的好处是它只使用两个列表中都存在的索引,因此您不必担心超出范围的错误。

    【讨论】:

      猜你喜欢
      • 2020-07-11
      • 1970-01-01
      • 2010-11-07
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 2020-01-06
      • 2021-12-12
      相关资源
      最近更新 更多