把一個字符串變成Unicode 碼位的列表
symbols = '$¢£¥€¤'
codes = []
for symbol in symbols:
codes.append(ord(symbol))
使用列表推導,代碼將非常簡潔
symbols = '$¢£¥€¤'
codes = [ord(symbol) for symbol in symbols]
使用列表推導計算笛卡兒積
colors = ['black', 'white']
sizes = ['S', 'M', 'L']
tshirts = [(color, size) for color in colors for size in sizes]
for tshirt in tshirts:
print(tshirt)
('black', 'S')
('black', 'M')
('black', 'L')
('white', 'S')
('white', 'M')
('white', 'L')
列表推導的作用只有一個:生成列表。如果想生成其他類型的序列,生成器表達式就派上了用場。
雖然也可以用列表推導來初始化元組、數組或其他序列類型,但是生成器表達式是更好的選擇。這是因為生成器表達式背后遵守了迭代器協議,可以逐個地產出元素,而不是先建立一個完整的列表,然后再把這個列表傳遞到某個構造函數里。前面那種方式顯然能夠節省內存。
用生成器表達式初始化元組和數組
symbols = '$¢£¥€¤'
# 如果生成器表達式是一個函數調用過程中的唯一參數,那么不需要額外再用括號把它圍起來。
tuple(ord(symbol) for symbol in symbols)
import array
# array 的構造方法需要兩個參數,因此括號是必需的。
array.array('I', (ord(symbol) for symbol in symbols))
下面使用生成器表達式計算笛卡兒積,與上面不同的是,用了生成器表達式后,內存里不會留下有6個組合的列表,因為生成器表達式會在每次for循環運行時才生成一個組合。
colors = ['black', 'white']
sizes = ['S', 'M', 'L']
for tshirt in ('{} {}'.format(color, size) for color in colors for size in sizes):
print(tshirt)
black S
black M
black L
white S
white M
white L
下面介紹元組,除了用作不可變的列表,它還可以用于沒有字段名的記錄。
把元組用作記錄
lax_coordinates = (33.9425, -118.408056)
city, year, pop, chg, area = ('Tokyo', 2003, 32450, 0.66, 8014)
traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'), ('ESP', 'XDA205856')]
# 下面三者等效
for passport in traveler_ids:
print('{}/{}'.format(*passport))
for country, id in traveler_ids:
print(country, id , sep='/')
for passport in traveler_ids:
print('%s/%s' %s passport)
元組拆包
元組拆包可以應用到任何可迭代對象上,唯一的硬性要求是,被可迭代對象中的元素數量必須要跟接受這些元素的元組的空檔數一致。除非我們用*
來表示忽略多余的元素。
一個很優雅的寫法當屬不使用中間變量交換兩個變量的值
>>> b, a = a, b
下面用*
來處理剩下的元素
>>> a, b, *rest = range(5)
>>> a, b, rest
(0, 1, [2, 3, 4])
>>> a, b, *rest = range(3)
>>> a, b, rest
(0, 1, [2])
>>> a, b, *rest = range(2)
>>> a, b, rest
(0, 1, [])
嵌套元組拆包
接受表達式的元組可以是嵌套式的,例如(a, b, (c, d))。只要這個接受元組的嵌套結構符合表達式本身的嵌套結構,Python 就可以作出正確的對應。
metro_areas = [
('Tokyo','JP',36.933,(35.689722,139.691667)),
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
]
print('{:15} | {:^9} | {:^9}'.format('', 'lat.', 'long.'))
fmt = '{:15} | {:9.4f} | {:9.4f}'
# 把輸入元組的最后一個元素拆包到由變量構成的元組里,這樣就獲取了坐標
for name, cc, pop, (latitude, longitude) in metro_areas:
if longitude <= 0:
print(fmt.format(name, latitude, longitude))
| lat. | long.
Mexico City | 19.4333 | -99.1333
New York-Newark | 40.8086 | -74.0204
Sao Paulo | -23.5478 | -46.6358