通过理解创建空列表
Creating empty lists with comprehension
我想获得有关此代码的一些帮助:
from datetime import datetime
flights = {
'09:35' : 'FREEPORT',
'09:55' : 'WEST END',
'10:45' : 'TREASURE CAY',
'11:45' : 'ROCK SOUND',
'12:00' : 'TREASURE CAY',
'17:00' : 'FREEPORT',
'17:55' : 'ROCK SOUND',
'19:00' : 'WEST END' }
def convert_to_ampm(time24: str) -> str:
return datetime.strptime(time24, '%H:%M').strftime('%I:%M %p')
flights_copy = {}
for k, v in flights.items():
if v not in flights_copy:
flights_copy[v] = []
flights_copy[v].append(k)
for k, v in flights_copy.items():
time = []
for item in v:
time.append(convert_to_ampm((item)))
print(k.title(), ':',time)
有没有办法让这段代码以理解的方式编写:
for k, v in flights.items():
if v not in flights_copy:
flights_copy[v] = []
flights_copy[v].append(k)
我目前正在学习Python,我的知识不是很丰富,也很抱歉我的英语水平很差。谢谢!
最简单的方法是使用 defaultdict
IMO:
from collections import defaultdict
flights_copy = defaultdict(list)
for k, v in flights.items():
flights_copy[v].append(k)
可以通过理解来做到这一点,但更困难——直接理解会覆盖值而不是附加值:
>>> {v: k for k, v in flights.items()}
{'FREEPORT': '17:00', 'WEST END': '19:00', 'TREASURE CAY': '12:00', 'ROCK SOUND': '17:55'}
所以你需要一个嵌套推导,一个为每个键构建值列表的内部列表推导:
>>> {v: [k for k, val in flights.items() if v == val] for v in flights.values()}
{'FREEPORT': ['09:35', '17:00'], 'WEST END': ['09:55', '19:00'], 'TREASURE CAY': ['10:45', '12:00'], 'ROCK SOUND': ['11:45', '17:55']}
请注意,这样做效率较低,因为现在您要多次遍历原始字典(从 O(n) 到 O(n^2))。
作为一个单一的理解,你至少可以这样做:
from itertools import groupby
from operator import itemgetter
flights_copy = {
v: [i[0] for i in d]
for v, d in groupby(sorted(flights.items(), key=itemgetter(1)), itemgetter(1))
}
所以如果航班是:{1: 20, 2: 20, 3: 10, 4: 15}
那么上面的代码会产生:{10: [3], 15: [4], 20: [1, 2]}
但是,您的初始代码是可读的并且工作正常。您可以通过以下方式对其进行一些改进:
from collections import defaultdict
flights_copy = defaultdict(list)
for k, v in flights.items():
flights_copy[v].append(k)
不是通过字典理解,而是通过使用 defaultdict
,在我看来这是非常可读的:
>>> from collections import defaultdict
>>> flights_copy_2 = defaultdict(list)
>>> for flight_time, flight_dest in flights.items():
... flights_copy_2[flight_dest].append(flight_time)
...
>>> print(dict(flights_copy_2))
{'FREEPORT': ['09:35', '17:00'], 'WEST END': ['09:55', '19:00'], 'TREASURE CAY': ['10:45', '12:00'], 'ROCK SOUND': ['11:45', '17:55']}
我想获得有关此代码的一些帮助:
from datetime import datetime
flights = {
'09:35' : 'FREEPORT',
'09:55' : 'WEST END',
'10:45' : 'TREASURE CAY',
'11:45' : 'ROCK SOUND',
'12:00' : 'TREASURE CAY',
'17:00' : 'FREEPORT',
'17:55' : 'ROCK SOUND',
'19:00' : 'WEST END' }
def convert_to_ampm(time24: str) -> str:
return datetime.strptime(time24, '%H:%M').strftime('%I:%M %p')
flights_copy = {}
for k, v in flights.items():
if v not in flights_copy:
flights_copy[v] = []
flights_copy[v].append(k)
for k, v in flights_copy.items():
time = []
for item in v:
time.append(convert_to_ampm((item)))
print(k.title(), ':',time)
有没有办法让这段代码以理解的方式编写:
for k, v in flights.items():
if v not in flights_copy:
flights_copy[v] = []
flights_copy[v].append(k)
我目前正在学习Python,我的知识不是很丰富,也很抱歉我的英语水平很差。谢谢!
最简单的方法是使用 defaultdict
IMO:
from collections import defaultdict
flights_copy = defaultdict(list)
for k, v in flights.items():
flights_copy[v].append(k)
可以通过理解来做到这一点,但更困难——直接理解会覆盖值而不是附加值:
>>> {v: k for k, v in flights.items()}
{'FREEPORT': '17:00', 'WEST END': '19:00', 'TREASURE CAY': '12:00', 'ROCK SOUND': '17:55'}
所以你需要一个嵌套推导,一个为每个键构建值列表的内部列表推导:
>>> {v: [k for k, val in flights.items() if v == val] for v in flights.values()}
{'FREEPORT': ['09:35', '17:00'], 'WEST END': ['09:55', '19:00'], 'TREASURE CAY': ['10:45', '12:00'], 'ROCK SOUND': ['11:45', '17:55']}
请注意,这样做效率较低,因为现在您要多次遍历原始字典(从 O(n) 到 O(n^2))。
作为一个单一的理解,你至少可以这样做:
from itertools import groupby
from operator import itemgetter
flights_copy = {
v: [i[0] for i in d]
for v, d in groupby(sorted(flights.items(), key=itemgetter(1)), itemgetter(1))
}
所以如果航班是:{1: 20, 2: 20, 3: 10, 4: 15}
那么上面的代码会产生:{10: [3], 15: [4], 20: [1, 2]}
但是,您的初始代码是可读的并且工作正常。您可以通过以下方式对其进行一些改进:
from collections import defaultdict
flights_copy = defaultdict(list)
for k, v in flights.items():
flights_copy[v].append(k)
不是通过字典理解,而是通过使用 defaultdict
,在我看来这是非常可读的:
>>> from collections import defaultdict
>>> flights_copy_2 = defaultdict(list)
>>> for flight_time, flight_dest in flights.items():
... flights_copy_2[flight_dest].append(flight_time)
...
>>> print(dict(flights_copy_2))
{'FREEPORT': ['09:35', '17:00'], 'WEST END': ['09:55', '19:00'], 'TREASURE CAY': ['10:45', '12:00'], 'ROCK SOUND': ['11:45', '17:55']}