An Array of Sequences(1)(含timeit 和 字符串格式化链接)

1.  Listcomps (List comprehensions) do everything the map and filter functions do. (map 函数和 filter函数能做的,列表生成式都可以做)

列表生成式和 map, filter 函数运行时间的比较示例:

import timeit

TIMES = 10000

SETUP = """
symbols = '$¢£¥€¤'
def non_ascii(c):
    return c > 127
"""
timeit.timeit()

def clock(label, cmd):
    res = timeit.repeat(cmd, setup=SETUP, number=TIMES)
    print(label, *('{:.3f}'.format(x) for x in res))


clock('listcomp        :', '[ord(s) for s in symbols if ord(s) > 127]')
clock('listcomp + func :', '[ord(s) for s in symbols if non_ascii(ord(s))]')
clock('filter + lambda :', 'list(filter(lambda c: c > 127, map(ord, symbols)))')
clock('filter + func   :', 'list(filter(non_ascii, map(ord, symbols)))')


# 测试一段代码的运行时间,可以用 timeit 模块
"""
timeit 模块中主要函数有两个:
1. timeit(stmt='pass', setup='pass', timer=<defaulttimer>, number=1000000)
    返回:
            返回执行stmt这段代码number遍所用的时间,单位为秒,float型

       参数:
            stmt:要执行的那段代码

            setup:执行代码的准备工作,不计入时间,一般是import之类的

            timer:这个在win32下是time.clock(),linux下是time.time(),默认的,不用管

            number:要执行stmt多少遍
            
2. repeat(stmt='pass', setup='pass', timer=<defaulttimer>, repeat=3, number=1000000)
    这个函数比timeit函数多了一个repeat参数而已,表示重复执行timeit这个过程多少遍,返回一个列表,表示执行每遍的时间;repeat默认为3
"""

timeit 参考链接:https://www.cnblogs.com/itcomputer/articles/4578769.html

 

2. Tuple

In [44]: traveler_ids = [('USA','31195855'), ('BRA','CE342567'), ('ESP', 'XDA205856')]

In [45]: for passport in sorted(traveler_ids):
    ...:     print('%s/%s' % passport)
    ...:
BRA/CE342567
ESP/XDA205856
USA/31195855

# The % formatting operator understands tuples and treats each item as a separate field.


# Tuple Unpacking
In [46]: t = (20, 8)

In [47]: divmod(*t)
Out[47]: (2, 4)

In [48]: quotient,remainder = divmod(*t)

In [49]: quotient, remainder
Out[49]: (2, 4)

# Using * to grab excess items
In [50]: a, b, *rest = range(5)

In [51]: a, b, rest
Out[51]: (0, 1, [2, 3, 4])

In [52]: a, b, *rest = range(2)

In [53]: a, b, rest
Out[53]: (0, 1, [])

In [54]: a, *body, c, d = range(5)

In [55]: a, body, c, d
Out[55]: (0, [1, 2], 3, 4)

# In the context of parallel assignment, the * prefix can be applied to exactly one variable, but it can appear in any position


# Nested Tuple Unpacking
metro_areas = [
    ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
    ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
    ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
]

print('{:15} | {:^9} | {:^9}'.format('', 'lat.', 'long.'))
fmt = '{:15} | {:9.4f} | {:9.4f}'

# By assigning the last field to a tuple, we unpack the coordinates.
for name, cc, pop, (latitude, longitude) in metro_areas:
    if longitude <= 0:
        print(fmt.format(name, latitude, longitude))


# Output:
"""
                |   lat.    |   long.  
Mexico City     |   19.4333 |  -99.1333
New York-Newark |   40.8086 |  -74.0204
"""

字符串格式化参考链接: https://www.cnblogs.com/songdanlee/p/11105807.html 

 

3. Named Tuples

from collections import namedtuple

# Build a namedtuple example 1:
# Card = namedtuple('Card', ['rank', 'suit'])

# 【Two parameters】 are required to create a named tuple: 【a class name】 and a 【list of field names】, which can be given by
# an 【iterable of strings】 or as 【a single space-delimited string】

In [57]: from collections import namedtuple

In [58]: City = namedtuple('City', 'name country population coordinates')

# Data must be passed as positional arguments to the constructor.
In [59]: tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))

In [60]: tokyo
Out[60]: City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))

In [61]: tokyo.population
Out[61]: 36.933

In [62]: tokyo.coordinates
Out[62]: (35.689722, 139.691667)

# You can access the fields by name or position
In [63]: tokyo[1]
Out[63]: 'JP'

In [64]:

In [64]:

# named tuple attributes: _fields -- class attribute; _make(iterable) -- class method; _asdict() -- instance method
In [64]: City._fields
Out[64]: ('name', 'country', 'population', 'coordinates')

In [65]: LatLong = namedtuple('LatLong', 'lat long')

In [66]: delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))

In [67]: delhi = City._make(delhi_data)

In [68]: delhi
Out[68]: City(name='Delhi NCR', country='IN', population=21.935, coordinates=LatLong(lat=28.613889, long=77.208889))

In [69]: delhi._asdict()
Out[69]:
OrderedDict([('name', 'Delhi NCR'),
             ('country', 'IN'),
             ('population', 21.935),
             ('coordinates', LatLong(lat=28.613889, long=77.208889))])

In [70]: for key, val in delhi._asdict().items():
    ...:     print(key + ':', val)
    ...:
name: Delhi NCR
country: IN
population: 21.935
coordinates: LatLong(lat=28.613889, long=77.208889)

"""
_fields is a tuple with the field names of the class.
_make() allow you to instantiate a named tuple from an iterable; City(*delhi_data) would do the same.
_asdict() returns a collections.OrderDict built from the named tuple instance.
"""

 

4. Slicing(切片)

4.1 Why Slices and Range Exclude the Last Item ?

"""
The Pythonic convention of excluding the last item in slices and ranges works well with the zero-based indexing used in Python,C and many other languages.
Some convenient features of the convention are :
1. It's easy to see the length of a slice or range when only the stop position is given: range(3) and my_list[:3] both produce three items.
2. It's easy to compute the length of a slice or range when start and stop are given: just subtract stop - start.
3. It's easy to split a sequence in two parts at any index x, without overlapping: simply get my_list[:x] and my_list[x:].
"""

4.2 Slice Object

示例: Line items from a flat-file invoice

invoice = """
0.....6.................................40...........52...55........
1909  Pimoroni PiBrella                      $17.50      3    $52.50
1489  6mm Tactile Switch x20                  $4.95      2     $9.90
1510  Panavise Jr. -PV -201                  $28.00      1    $28.00
1601  PiTFT Mini Kit 320x240                 $34.95      1    $34.95
"""

# assign name to slices
SKU = slice(0, 6)
DESCRIPTION = slice(6, 40)
UNIT_PRICE = slice(40, 52)
QUANTITY = slice(52, 55)
ITEM_TOTAL = slice(55, None)

line_items = invoice.split('\n')

print(line_items)
"""
Output:
['', '0.....6.................................40...........52...55........', '1909  Pimoroni PiBrella                      $17.50      3    $52.50', '1489  6mm Tactile Switch x20                  $4.95      2     $9.90', '1510  Panavise Jr. -PV -201                  $28.00      1    $28.00', '1601  PiTFT Mini Kit 320x240                 $34.95      1    $34.95', '']
"""

line_items = invoice.split('\n')[2:]

for item in line_items:
    print(item[UNIT_PRICE], item[DESCRIPTION])

# sequence[slice]
"""
Output:
     $17.50  Pimoroni PiBrella                 
      $4.95  6mm Tactile Switch x20            
     $28.00  Panavise Jr. -PV -201             
     $34.95  PiTFT Mini Kit 320x240
"""


"""
解释:
The notation a:b:c is only valid within [] when used in the indexing or subscript operator, and it produces a slice object:slice(a, b, c). To evaluate the expression seq[start:stop:step], 
Python calls seq.__getitem__(slice(start, stop, step))
"""

4.3 Building Lists of Lists (Using + and * with Sequences)

"""
To initialize a list of lists as my_list = [[]] * 3 will result in a list with three references to the same inner list.
e.g.
In [47]: my_list = [[]] * 3

In [48]: my_list
Out[48]: [[], [], []]
# Out[48] 中的三个 [] 指向同一个内存地址

In [49]: my_list[0] is my_list[1] and my_list[1] is my_list[2]
Out[49]: True
"""

"""
The best way of initializing a list with a certain number of nested lists is with a list comprehension.
生成列表中嵌套列表 最好的方式是 列表生成式
"""

# Right example:
# Example 2-12
board = [[] for i in range(3)]
print(board)
# 输出:
# [[], [], []]

print(board[0] is board[1] and board[1] is board[2])
# 输出:
# False
# False 表示 生成的三个空列表不是指向同一个内存地址(这正是我们想要的)

board[1].append('a')
print(board)
# 输出:
# [[], ['a'], []]


# Wrong example:
# Example 2-13
weird_board = [[]] * 3
print(weird_board)
# 输出:
# [[], [], []]

print(weird_board[0] is weird_board[1] and weird_board[1] is weird_board[2])
# 输出:
# True
# 上面的 True 表示 三个空列表指向了同一个内存地址

weird_board[1].append('a')
print(weird_board)
# 输出:
# [['a'], ['a'], ['a']]


# 上述的错误例子 Example 2-13 等价于下面的操作:
row = []
board_wrong = []
for i in range(3):
    board_wrong.append(row)     # The same row is appended three times to board_wrong.
print(board_wrong)
# 输出:
# [[], [], []]


# 上述正确的例子 Example 2-12 等价于下面的操作:
board_right = []
for i in range(3):
    row = []    # 每次 for 循环时都对 row 重新赋值
    board_right.append(row)     # Each iteration builds a new row and appends it to borad_right.
board_right[1].append('b')
print(board_right)
# 输出:
# [[], ['b'], []]

 

end

posted @ 2020-01-01 13:24  neozheng  阅读(223)  评论(0编辑  收藏  举报