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

2020-04-29 09:41:08 +08:00
 Tianny
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 。以此类推。这些值都算出来后,再从中取个最大的。

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

3818 次点击
所在节点    Python
22 条回复
xpresslink
2020-04-29 09:53:07 +08:00
你的问题本身是错误的,不存在的。
Tianny
2020-04-29 09:56:19 +08:00
@xpresslink 描述的可能有点小问题。
ericls
2020-04-29 09:56:33 +08:00
max(sum(next(j[i] for j in a if j.get(i)) for i in k) for k in b)
renmu123
2020-04-29 09:57:48 +08:00
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
2020-04-29 09:58:09 +08:00
max(map(lambda x: sum(map(lambda y: a[y], x)), b))
ericls
2020-04-29 09:58:49 +08:00
@layorlayor a 不是一个 dict 不可以 __getitem__
luhuisicnu
2020-04-29 10:37:33 +08:00
出题内容都不是 python 代码,费多大劲来理解题意?
flycat1626
2020-04-29 10:40:23 +08:00
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
2020-04-29 10:54:30 +08:00
你把问题拆解成小问题不就可以解了?你可以这样拆:

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

可以看看官方文档,https://docs.python.org/3/library/functions.html?highlight=enumerate#enumerate
xpresslink
2020-04-29 11:38:39 +08:00
终于看明白你的需求了,看下面:
>>> 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
2020-04-29 12:12:22 +08:00
楼上一行代码的估计就是不想让楼主小白看懂🐶
xpresslink
2020-04-29 12:15:46 +08:00
@yangzzzzzzzt1 其实我是为了培养楼主最正统的 pythonic 思维方式和代码风格。
Pagliacii
2020-04-29 12:32:01 +08:00
@xpresslink #16 有点揠苗助长了,在他懂的情况下再告诉他可以用更简短的方式写出来才合理吧,在他不懂的情况下看到这么复杂的一行代码估计更加不懂了

毕竟 The Zen of Python 里也说了,Simple is better than complex.
princelai
2020-04-29 13:32:26 +08:00
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
2020-04-29 13:36:03 +08:00
得到 argmax 之后,只需要 df.iloc[idx].to_list()
idx 就是 argmax 的值就能取回对应的列表
Tianny
2020-04-29 17:41:02 +08:00
@xpresslink 真大神 哈哈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/667168

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX