V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Tianny
V2EX  ›  Python

问个 Python 代码的小问题,困扰了半天。不会解。

  •  
  •   Tianny · 2020-04-29 09:41:08 +08:00 · 3802 次点击
    这是一个创建于 1450 天前的主题,其中的信息可能已经有所发展或是发生改变。
    a = [{a: 1}, {b: 2}, {c: 3}]
    b = [[c, b], [c, a], [b, a], [c, b, a]]
    

    问题:求 b 里面每个列表的元素在 a 的字典里面对应的值的和。算出这些值后,再取出最大值。 比如 [c,b] 这个集合,那么它的值就是 就是 3+2 。[c,a] 的值就是 3+1 。以此类推。这些值都算出来后,再从中取个最大的。

    希望大佬们能给个详细的代码。谢谢。

    22 条回复    2020-05-01 19:37:07 +08:00
    xpresslink
        1
    xpresslink  
       2020-04-29 09:53:07 +08:00
    你的问题本身是错误的,不存在的。
    Tianny
        2
    Tianny  
    OP
       2020-04-29 09:56:19 +08:00
    @xpresslink 描述的可能有点小问题。
    ericls
        3
    ericls  
       2020-04-29 09:56:33 +08:00   ❤️ 3
    max(sum(next(j[i] for j in a if j.get(i)) for i in k) for k in b)
    renmu123
        4
    renmu123  
       2020-04-29 09:57:48 +08:00   ❤️ 1
    a = [{'a': 1}, {'b': 2}, {'c': 3}, {'d': 10}]
    b = [['c', 'd'], ['c', 'a'], ['b', 'a'], ['c', 'b', 'a']]
    a_dict = {list(d.keys())[0]: list(d.values())[0] for d in a}

    array = []
    for data in b:
    array.append([a_dict[d] for d in data])
    print(array)
    print(max(array))

    只要把 a 做成一个字典,再对 b 遍历一下就好了
    layorlayor
        5
    layorlayor  
       2020-04-29 09:58:09 +08:00   ❤️ 3
    max(map(lambda x: sum(map(lambda y: a[y], x)), b))
    ericls
        6
    ericls  
       2020-04-29 09:58:49 +08:00
    @layorlayor a 不是一个 dict 不可以 __getitem__
    luhuisicnu
        7
    luhuisicnu  
       2020-04-29 10:37:33 +08:00
    出题内容都不是 python 代码,费多大劲来理解题意?
    flycat1626
        8
    flycat1626  
       2020-04-29 10:40:23 +08:00   ❤️ 1
    a = [{'a': 1}, {'b': 2}, {'c': 3}]
    b = [['c', 'b'], ['c', 'a'], ['b', 'a'], ['c', 'b', 'a']]

    temp = {}
    for item in a:
    temp.update(item)
    max = 0
    for item in b:
    res = 0
    for i in item:
    res += temp.get(i,0)
    if res > max:
    max = res
    print max
    Pagliacii
        9
    Pagliacii  
       2020-04-29 10:54:30 +08:00   ❤️ 1
    你把问题拆解成小问题不就可以解了?你可以这样拆:

    1. a 列表不变,然后 b = ['c', 'b'],你要怎么求出以 b 列表中的元素为 key,从 a 中取出对应 key 的值并求和呢?
    ```python
    a = [{'a': 1}, {'b': 2}, {'c': 3}]
    b = ['c', 'b']
    sum_val = 0

    for elem in b:
    for pair in a:
    sum_val += pair.get(elem, 0)

    print(sum_val)
    ```

    2. 接下来就是 b 是嵌套列表,也就是你的题目了,求和之后求最大值。如果问题 1 能解,问题 2 也就不难了
    ```python
    a = [{'a': 1}, {'b': 2}, {'c': 3}]
    b = [['c', 'b'], ['c', 'a'], ['b', 'a'], ['c', 'b', 'a']]
    max_val = 0

    for elem in b:
    sum_val = 0
    for key in elem:
    for pair in a:
    sum_val += pair.get(key, 0)
    max_val = max_val if max_val >= sum_val else sum_val

    print(max_val)
    ```
    Pagliacii
        10
    Pagliacii  
       2020-04-29 10:56:24 +08:00
    @Pagliacii #9 呃,Markdown 写习惯了
    Pagliacii
        11
    Pagliacii  
       2020-04-29 10:59:42 +08:00
    @Tianny 总之就是如果问题对于你来说很复杂,那么你就尝试把问题简化,简化到你能解决为止。然后基于你能解决的问题,再一步步回到原来的问题。这样做的话,再复杂的问题也能迎刃而解了。当然,前提是问题有解。
    Tianny
        12
    Tianny  
    OP
       2020-04-29 11:04:50 +08:00
    @Pagliacii 拿到最大之后,我怎么再重新拿回对应的集合呢。比如计算出来 max_val 是 6,那么反溯回去,是 [c,b,a] 这个算出来的。我怎么再回头拿到 ['c', 'b', 'a']。
    Pagliacii
        13
    Pagliacii  
       2020-04-29 11:11:57 +08:00
    枚举列表啊,enumerate(b),可以在遍历列表元素的同时获得该元素在列表中的索引。

    可以看看官方文档,https://docs.python.org/3/library/functions.html?highlight=enumerate#enumerate
    xpresslink
        14
    xpresslink  
       2020-04-29 11:38:39 +08:00   ❤️ 2
    终于看明白你的需求了,看下面:
    >>> a = [{'a': 1}, {'b': 2}, {'c': 3}, {'d': 10}]
    >>> b = [['c', 'd'], ['c', 'a'], ['b', 'a'], ['c', 'b', 'a']]
    >>> from collections import ChainMap
    >>> dict_a= ChainMap(*a)
    >>> [sum(dict_a[j] for j in i) for i in b]
    [13, 4, 3, 6]
    >>> max(b, key=lambda i: sum( dict_a[j] for j in i))
    ['c', 'd']
    yangzzzzzzzt1
        15
    yangzzzzzzzt1  
       2020-04-29 12:12:22 +08:00
    楼上一行代码的估计就是不想让楼主小白看懂🐶
    xpresslink
        16
    xpresslink  
       2020-04-29 12:15:46 +08:00
    @yangzzzzzzzt1 其实我是为了培养楼主最正统的 pythonic 思维方式和代码风格。
    Pagliacii
        17
    Pagliacii  
       2020-04-29 12:32:01 +08:00
    @xpresslink #16 有点揠苗助长了,在他懂的情况下再告诉他可以用更简短的方式写出来才合理吧,在他不懂的情况下看到这么复杂的一行代码估计更加不懂了

    毕竟 The Zen of Python 里也说了,Simple is better than complex.
    princelai
        18
    princelai  
       2020-04-29 13:32:26 +08:00   ❤️ 1
    from collections import ChainMap

    ad = dict(ChainMap(*a))

    方法一
    import pandas as pd
    df = pd.DataFrame(b)
    df.applymap(lambda x:ad.get(x)).sum(axis=1).argmax()

    方法二
    import numpy as np
    np.array([sum([ad.get(j) for j in i]) for i in b]).argmax()

    这两个是取第几个是最大值,如果只取最大那么只取 max 就好了,numpy 都不需要
    princelai
        19
    princelai  
       2020-04-29 13:36:03 +08:00
    得到 argmax 之后,只需要 df.iloc[idx].to_list()
    idx 就是 argmax 的值就能取回对应的列表
    Tianny
        20
    Tianny  
    OP
       2020-04-29 17:41:02 +08:00
    @xpresslink 真大神 哈哈
    Tianny
        21
    Tianny  
    OP
       2020-04-29 17:41:53 +08:00
    感谢各位~
    lizhenjia569
        22
    lizhenjia569  
       2020-05-01 19:37:07 +08:00
    首先请楼主明确提问代码中的数据类型!

    1 、a 是字典还是列表?如果是列表,其中的元素是字典吗?字典只有一个元素吗?每个字典元素会存在重复键吗?
    2 、a 、b 、c 是不同的变量还是键名?如果是键名最好使用字符串形式给出。

    a 是一个列表:可以参考 @xpresslink 的代码使用 ChainMap

    a 是一个字典:可以使用 max 和 sum 函数对 列表进行迭代:

    max((sum((a[e] for e in ele if a.get(e))) for ele in b))
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3335 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:34 · PVG 20:34 · LAX 05:34 · JFK 08:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.