我有一个嵌套列表,如下所示:
[['Vienna','2012', 890,503,70],['London','2014', 5400, 879,78],
['London','2014',4800,70,90],['Bern','2013',300,450,678],
['Vienna','2013', 700,850,90], ['Bern','2013',500,700,90]]
如果城市和年份相等,我想要做的是将子列表中的每个整数值与另一个子列表相加。我首先想到的是一本以城市和年份为关键字典的词典,但却导致排序问题。
然后我有:{('Vienna','2012'):[890,503,70],('Bern','2013'):[800,1150,768],...}
我也试过这样的事情:
[sum(x) for x in zip(*list) if x[0] == x[0]]
但当然没有用。
我可以使用嵌套列表执行此类操作,以便按城市和年份对其进行排序会更容易吗?
答案 0 :(得分:2)
您可以构造一个结果dict
,其中key是原始列表中前两个项的元组,值是list
个数字。每次向dict
添加值时,都可以使用get
返回现有元素或给定默认值,在本例中为空列表。
在您要添加现有列表和列表后,您可以使用zip_longest
和fillvalue
来获取两个列表中要求的数字。 zip_longest
返回长度为2的元组,每个列表包含一个数字。如果一个列表长于其他fillvalue
用作默认值,那么这也适用于列表具有不同长度的情况。最后,列表理解可用于对每个项目求和一个新值:
from itertools import zip_longest
l = [
['Vienna','2012', 890,503,70],['London','2014', 5400, 879,78],
['London','2014',4800,70,90],['Bern','2013',300,450,678],
['Vienna','2013', 700,850,90], ['Bern','2013',500,700,90]
]
res = {}
for x in l:
key = tuple(x[:2])
res[key] = [i + j for i, j in zip_longest(res.get(key, []), x[2:], fillvalue=0)]
print(res)
输出:
{('Vienna', '2013'): [700, 850, 90], ('London', '2014'): [10200, 949, 168],
('Vienna', '2012'): [890, 503, 70], ('Bern', '2013'): [800, 1150, 768]}
如果您想要按字母顺序对城市进行排序,请先将最近年份排序,然后将自定义key
传递给sorted
:
for item in sorted(res.items(), key=lambda x: (x[0][0], -int(x[0][1]))):
print(item)
输出:
(('Bern', '2013'), [800, 1150, 768])
(('London', '2014'), [10200, 949, 168])
(('Vienna', '2013'), [700, 850, 90])
(('Vienna', '2012'), [890, 503, 70])
答案 1 :(得分:1)
您只需使用字典将所有国家/地区名称和年份存储为一个值,即可获得所需的结果。字典中的每个键都是国家名称和相应年份的元组。
例如:key = (country,year)
。
这使我们拥有分组时所需要的唯一值。
L = [
['Vienna','2012', 890,503,70],['London','2014', 5400, 879,78],
['London','2014',4800,70,90],['Bern','2013',300,450,678],
['Vienna','2013', 700,850,90], ['Bern','2013',500,700,90]
]
countries = {}
for list in L:
key = tuple(list[0:2])
values = list[2:]
if key in countries:
countries[key] = [sum(v) for v in zip(countries[key],values)]
else:
countries[key] = values
print(countries)
退出:
{
('Vienna', '2012'): [890, 503, 70],
('London', '2014'): [10200, 949, 168],
('Bern', '2013'): [800, 1150, 768],
('Vienna', '2013'): [700, 850, 90]
}
答案 2 :(得分:0)
您应该按照问题中的概述维护字典。这样的事情会有所帮助,
cities = {}
for a in list:
city_key = a[:1]
if city_key in cities:
cities[city_key] = [a + b for a, b in zip(a[2:], cities[city_key])]
else:
cities[city_tuple] = a[2:]
答案 3 :(得分:0)
一种方法是通过您想要的密钥(城市和年份)将列表列表拆分为字典。此外,defaultdict
有助于将所有距离压缩成平面列表
>>> from collections import defaultdict
>>> dct = defaultdict(list)
>>> for item in lst:
... dct[(item[0], item[1])].extend(item[2:])
现在dct
具有按城市和年份分组的整数:
>>> dct
defaultdict(<type 'list'>, {('Vienna', '2013'): [700, 850, 90], ('London', '2014'): [5400, 879, 78, 4800, 70, 90], ('Vienna', '2012'): [890, 503, 70], ('Bern', '2013'): [300, 450, 678, 500, 700, 90]})
你可以总结一下:
>>> for key in dct:
... print(key, sum(dct[key]))
...
(('Vienna', '2013'), 1640)
(('London', '2014'), 11317)
(('Vienna', '2012'), 1463)
(('Bern', '2013'), 2718)
答案 4 :(得分:0)
import akka.actor.{Actor, ActorRef}
import akka.pattern._
class Registry extends Actor {
import Registry._
var registry:Map[String, Any] = Map()
def receive = {
case Lookup(name) => sender ! registry.get(name)
}
}
object Registry {
import akka.actor.{ActorSystem, Props}
case class Lookup(name: String)
// create dedicated actor infrastructure
val system = ActorSystem("myActorInfrastructure")
// create actor with a name and register it with the infrastructure
def apply(name: String) = system.actorOf(Props(new Registry()), name)
}
class Tweeter(val name: String, val regist:Registry, var followers:List[ActorRef]=List()) extends Actor{
import Tweeter._
def receive = {
case Follow(user) => {
//Here is the error
(regist!? Lookup(name)) match{
case Some(a:ActorRef) => a ! AddFollower(sender)
}
}
case AddFollower(follower) => followers = follower::followers
}
}
object Tweeter {
import akka.actor.{ActorSystem, Props}
case class Follow(user: String)
case class AddFollower(follower: ActorRef)
def apply(name: String, annuaire:Registry) = Registry.system.actorOf(Props(new Tweeter(name,annuaire)))
}
out:
nl = [['Vienna','2012', 890,503,70],['London','2014', 5400, 879,78],
['London','2014',4800,70,90],['Bern','2013',300,450,678],
['Vienna','2013', 700,850,90], ['Bern','2013',500,700,90]]
d = {}
for l in nl:
key = l[0] , l[1]
value = l[2:]
if key not in d:
d[key] = value
else:
d[key] = [sum(i)for i in zip(d[key], value)]
print(d)
答案 5 :(得分:0)
使用itertools.groupby
和operator.itemgetter
函数的解决方案:
import itertools, operator
l = [['Vienna','2012', 890,503,70],['London','2014', 5400, 879,78],
['London','2014',4800,70,90],['Bern','2013',300,450,678],
['Vienna','2013', 700,850,90], ['Bern','2013',500,700,90]]
getter = operator.itemgetter(0, 1) # the sequence to be grouped(first two items)
summed = [[k[0],k[1],sum(sum(d[2:]) for d in list(group))]
for k, group in itertools.groupby(sorted(l, key=getter), getter)]
print(summed)
输出:
[['Bern', '2013', 2718], ['London', '2014', 11317], ['Vienna', '2012', 1463], ['Vienna', '2013', 1640]]