0. Overview of Built-in Sequences

  • Container sequences

list , tuple , and collections.deque can hold items of different types.

  • Flat sequences
    str , bytes , bytearray , memoryview , and array.array hold items of one type.

Container sequences hold references to the objects they contain, which may be of any type, while flat sequences physically store the value of each item within its own memory space, and not as distinct objects. Thus, flat sequences are more compact, but they are limited to holding primitive values like characters, bytes, and numbers.

Another way of grouping sequence types is by mutability:

  • Mutable sequences

list , bytearray , array.array , collections.deque , and memoryview

  • Immutable sequences

tuple , str , and bytes

1. List Comprehensions

A powerful way of building lists that is somewhat underused because the syntax may be unfamiliar.

Two Example

  1. >>> symbols = '$¢£¥€¤'
  2. >>> codes = []
  3. >>> for symbol in symbols:
  4. codes.append(ord(symbol))
  5. >>> codes
  6. [36, 162, 163, 165, 8364, 164]
  7. Versus
  8. >>> symbols = '$¢£¥€¤'
  9. >>> codes = [ord(symbol) for symbol in symbols]
  10. >>> codes
  11. [36, 162, 163, 165, 8364, 164]

A for loop may be used to do lots of different things. In contrast, a listcomp is meant to do one thing only: to build a new list.

Syntax Tip — 换行符在 括号对 间可省略 In Python code, line breaks are ignored inside pairs of [] , {} , or () . So you can build multiline lists, listcomps, genexps, dictionaries and the like without using the ugly \ line continuation escape.

Syntax Tip — 列表生成式 及 生成器 有自己的作用域 List comprehensions, generator expressions, and their siblings set and dict comprehensions now have their own local scope.

  1. >> x = 'ABC'
  2. >> dummy = [ord(x) for x in x]
  3. >> x
  4. 'ABC'
  5. >> dummy
  6. [65, 66, 67]

2. Generator Expression

To initialize tuples, arrays, and other types of sequences, you could also start from a listcomp, but a genexp saves memory because it yields items one by one using the iterator protocol instead of building a whole list just to feed another constructor.

Genexps use the same syntax as listcomps, but are enclosed in parentheses ()`` rather than brackets [] .

Example:

  1. >>> colors = ['black', 'white']
  2. >>> sizes = ['S', 'M', 'L']
  3. >>> for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):
  4. ... print(tshirt)

3. Touple as Records and Immutable Lists

Tuples do double duty: they can be used as immutable lists and also as records with no field names.

3.1 Tuple as Records

The meaning of each data item is given by its position in the tuple.

  1. >>> traveler_ids = [('USA', '31195855'), ('BRA', 'CE342567'),
  2. ('ESP', 'XDA205856')]
  3. >>> for passport in sorted(traveler_ids):
  4. print('%s/%s' % passport)
  5. BRA/CE342567
  6. ESP/XDA205856
  7. USA/31195855

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

  1. >>> for country, _ in traveler_ids:
  2. print(country)
  3. USA
  4. BRA
  5. ESP

The for loop knows how to retrieve the items of a tuple separately—this is called “unpacking”. — 解包

3.1.1 Unpacking

对于可迭代对象,都可以进行解包赋值操作。

Example1

  1. In [1]: a,b,c = [1, '2', 3]
  2. In [5]: a,b,c
  3. Out[5]: (1, '2', 3)
  4. In [6]: a,b,c = 'abc'
  5. In [7]: a,b,c
  6. Out[7]: ('a', 'b', 'c')
  7. In [8]: a,b,c = {'h':1, 'g':2, 'k':3}.items()
  8. In [9]: a,b,c
  9. Out[9]: (('h', 1), ('g', 2), ('k', 3))

3.1.2 Extended Iterable Unpacking — PEP 3132

This PEP proposes a change to iterable unpacking syntax, allowing to specify a “catch-all” name which will be assigned a list of all items not assigned to a “regular” name.

The variable used starred expression will be a list after assignment.

  1. >>> a, *b, c = range(5)
  2. >>> a
  3. 0
  4. >>> c
  5. 4
  6. >>> b
  7. [1, 2, 3]

A tuple (or list) on the left side of a simple assignment (unpacking is not defined for augmented assignment) may contain at most one** expression prepended with a single asterisk** (which is henceforth called a “starred” expression, while the other expressions in the list are called “mandatory”). This designates a subexpression that will be assigned a list of all items from the iterable being unpacked that are not assigned to any of the mandatory expressions, or an empty list if there are no such items.

For example, if seq is a slicable sequence, all the following assignments are equivalent if seq has at least three elements:

  1. a, b, c = seq[0], list(seq[1:-1]), seq[-1]
  2. a, *b, c = seq
  3. [a, *b, c] = seq
  4. >>> a, b, *rest = range(5)
  5. >>> a, b, rest
  6. (0, 1, [2, 3, 4])
  7. >>> a, b, *rest = range(3)
  8. >>> a, b, rest
  9. (0, 1, [2])
  10. >>> a, b, *rest = range(2)
  11. >>> a, b, rest
  12. (0, 1, [])

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

  1. >>> a, *body, c, d = range(5)
  2. >>> a, body, c, d
  3. (0, [1, 2], 3, 4)
  4. >>> *head, b, c, d = range(5)
  5. >>> head, b, c, d
  6. ([0, 1], 2, 3, 4)

IMPORTANT:
Starred expressions are only allowed as assignment targets, using them anywhere else (except for star-args in function calls, of course) is an error.

错误场景

  1. the iterable doesn’t contain enough items to assign to all the mandatory expressions.

Such as a, b, c = 1, 2 ;

  1. use the starred expression as a lone assignment target: such as *a = range(5).

The correct assignemnt way of writing is : *a,`` = range(5) .

3.2 Named Tuples

The collections.namedtuple function is a factory that produces subclasses of tuple enhanced with field names and a class name. — 用字典的方式,访问元祖,保留了元祖的有序性。

You can access the fields by name or position.
Example

  1. >>> from collections import namedtuple
  2. >>> City = namedtuple('City', 'name country population coordinates')
  3. >>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
  4. >>> tokyo
  5. City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722,
  6. 139.691667))
  7. >>> tokyo.population
  8. 36.933
  9. >>> tokyo.coordinates
  10. (35.689722, 139.691667)
  11. >>> tokyo[1]
  12. 'JP'

3.2.1 Useful Attributes and Methods

3.2.1.1 attribute: _fields

_fields is a tuple with the field names of the class:

  1. >>> City._fields
  2. ('name', 'country', 'population', 'coordinates')

3.2.1.2 method: _make(iterable)

_make() allow you to instantiate a named tuple from an iterable; City(*del hi_data) would do the same:

  1. >>> LatLong = namedtuple('LatLong', 'lat long')
  2. >>> delhi_data = ('Delhi NCR', 'IN', 21.935, LatLong(28.613889, 77.208889))
  3. >>> delhi = City._make(delhi_data)

3.2.1.3 method: _asdict()

_asdict() returns a collections.OrderedDict built from the named tuple instance. That can be used to produce a nice display of city data:

  1. >>> delhi._asdict()
  2. OrderedDict([('name', 'Delhi NCR'), ('country', 'IN'), ('population',
  3. 21.935), ('coordinates', LatLong(lat=28.613889, long=77.208889))])
  4. >>> for key, value in delhi._asdict().items():
  5. print(key + ':', value)
  6. name: Delhi NCR
  7. country: IN
  8. population: 21.935
  9. coordinates: LatLong(lat=28.613889, long=77.208889)

3.3 Tuples as Immutable Lists

List&Tuple - 图1
List&Tuple - 图2

4. Slicing

4.1 Step

class slice(object)
| slice(stop)
| slice(start, stop[, step])

s[a:b:c] can be used to specify a stride or step c , causing the resulting slice to skip items. The stride can also be negative, returning items in reverse. Three examples make this clear:

When step is positive, means [start, stop) :

  1. >>> s = 'bicycle'
  2. >>> s[::3]
  3. 'bye'
  4. >>> s[1:5:2]
  5. 'iy'

When step is negative, means [stop, start) :

  1. In [70]: st = "0123456789"
  2. In [71]: st[::-1]
  3. Out[71]: '9876543210'
  4. In [72]: st[:1:-1]
  5. Out[72]: '98765432' # not include position 0 and 1
  6. In [73]: st[:2:-1]
  7. Out[73]: '9876543' # not include position 0, 1 and 2

4.2 A good example with slice object

class slice(object)
| slice(stop)
| slice(start, stop[, step])

Usage: iterable[slice_obj]

  1. In [98]: SLICE = slice(1,3)
  2. In [99]: st
  3. Out[99]: '0123456789'
  4. In [100]: st[SLICE]
  5. Out[100]: '12'

Example 2-11. Line items from a flat-file invoice

  1. >>> invoice = """
  2. ... 0.....6.................................40........52...55........
  3. ... 1909 Pimoroni PiBrella $17.50 3 $52.50
  4. ... 1489 6mm Tactile Switch x20 $4.95 2 $9.90
  5. ... 1510 Panavise Jr. - PV-201 $28.00 1 $28.00
  6. ... 1601 PiTFT Mini Kit 320x240 $34.95 1 $34.95
  7. ... """
  8. >>> SKU = slice(0, 6)
  9. >>> DESCRIPTION = slice(6, 40)
  10. >>> UNIT_PRICE = slice(40, 52)
  11. >>> QUANTITY = slice(52, 55)
  12. >>> ITEM_TOTAL = slice(55, None)
  13. >>> line_items = invoice.split('\n')[2:]
  14. >>> for item in line_items:
  15. ... print(item[UNIT_PRICE], item[DESCRIPTION])
  16. ...
  17. $17.50 Pimoroni PiBrella
  18. $4.95 6mm Tactile Switch x20
  19. $28.00 Panavise Jr. - PV-201
  20. $34.95 PiTFT Mini Kit 320x240

4.3 Assigning to Slices

Mutable sequences can be grafted, excised, and otherwise modified in place using slice notation on the left side of an assignment statement or as the target of a del statement. — 切片赋值

  1. >>> l = list(range(10))
  2. >>> l[2:5] = [20, 30]
  3. >>> l
  4. [0, 1, 20, 30, 5, 6, 7, 8, 9] # slice assignment only affects the same cnt
  5. # value on the right side
  6. >>> l[2:5] = 100 # slice assignment, right side must be iterable obj
  7. Traceback (most recent call last):
  8. File "<stdin>", line 1, in <module>
  9. TypeError: can only assign an iterable
  10. >>> l[2:5] = [100]
  11. >>> l
  12. [0, 1, 100, 22, 9]

5. + * with Sequences

5.1 Basic Usage

Python programmers expect that sequences support + and . Usually both operands of + must be of the same sequence type, and neither of them is modified but a new sequence of the same type is created as result of the concatenation.
To concatenate multiple copies of the same sequence, multiply it by an integer. Again, *a new sequence
is created.

  1. >>> l = [1, 2, 3]
  2. >>> l * 5
  3. [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
  4. >>> 5 * 'abcd'
  5. 'abcdabcdabcdabcdabcd'

5.2 Building lists of lists

Wrong Example:

  1. >>> weird_board = [['_'] * 3] * 3
  2. >>> weird_board
  3. [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
  4. >>> weird_board[1][2] = 'O'
  5. >>> weird_board
  6. [['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]
  7. >>> [id(x) for x in weird_board]
  8. [7696541285704, 7696541285704, 7696541285704] # the same reference

Same as:

  1. row = ['_'] * 3
  2. board = []
  3. for i in range(3):
  4. board.append(row) # The same row is appended three times to board

Right Example:

  1. >>> weird_board = [['_'] * 3 for i in range(3)] # list comprehension
  2. >>> weird_board
  3. [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
  4. >>> weird_board[0][2] = 'X'
  5. >>> weird_board
  6. [['_', '_', 'X'], ['_', '_', '_'], ['_', '_', '_']]
  7. >>> [id(i) for i in weird_board]
  8. [7696541284936, 7696541281800, 7696522634888] # 3 seperate reference

Same as:

  1. board = []
  2. for i in range(3):
  3. row = ['_'] * 3 # create a new list each time
  4. board.append(row) # add a new reference each time

Last — used module

1. ord

ord(c, /)
Return the Unicode code point for a one-character string.

2. filter

class filter(object)
| filter(function or None, iterable) —> filter object — 对可迭代对象进行筛选,筛选条件为 function 返回 true,或
| — 迭代对象的item为true
| Return an iterator yielding those items of iterable for which function(item)
| is true. If function is None, return the items that are true.

  1. In [10]: x = 'abc'
  2. In [11]: dummy = [ord(x) for x in x]
  3. In [16]: list(filter(lambda x: x >= 98, dummy))
  4. Out[16]: [98, 99]

3. map

class map(object)
| map(func, *iterables) —> map object — 对多个iterable对象进行func操作,iterables的个数,应该与func的参数个数一致
| — 组成一个可迭代对象map
| Make an iterator that computes the function using arguments from
| each of the iterables. Stops when the shortest iterable is exhausted.

  1. In [21]: list(map(ord, ['a','b','c']))
  2. Out[21]: [97, 98, 99]
  1. In [5]: list(map(lambda x,y : x + y, ['a','b','c'],['d','e','f']))
  2. Out[5]: ['ad', 'be', 'cf']

4. array.array

Flat sequence, mutable.

class array(builtins.object)
| array(typecode [, initializer]) -> array — 将同一类型的数值,组成一个array对象 (类似于C语言的数组)
|
| Return a new array whose items are restricted by typecode, and
| initialized from the optional initializer value, which must be a list,
| string or iterable over elements of the appropriate type.
|
| Arrays represent basic values and behave very much like lists, except
| the type of objects stored in them is constrained. The type is specified
| at object creation time by using a type code, which is a single character.
| The following type codes are defined:
|
| Type code C Type Minimum size in bytes
| ‘b’ signed integer 1
| ‘B’ unsigned integer 1
| ‘u’ Unicode character 2 (see note)
| ‘h’ signed integer 2
| ‘H’ unsigned integer 2
| ‘i’ signed integer 2
| ‘I’ unsigned integer 2
| ‘l’ signed integer 4
| ‘L’ unsigned integer 4
| ‘q’ signed integer 8 (see note)
| ‘Q’ unsigned integer 8 (see note)
| ‘f’ floating point 4
| ‘d’ floating point 8

5. zip

class zip(object)
| zip(iter1 [,iter2 […]]) —> zip object — 将多个iter对象 按位置组成一个可迭代的对象zip(每个迭代生成一个元祖)
|
| Return a zip object whose .next() method returns a tuple where
| the i-th element comes from the i-th iterable argument. The .next()
| method continues until the shortest iterable in the argument sequence
| is exhausted and then it raises StopIteration.

  1. In [2]: list(zip([1,2,3,4]))
  2. Out[2]: [(1,), (2,), (3,), (4,)]
  3. In [9]: list(zip([1,2,3],[4,5,6]))
  4. Out[9]: [(1, 4), (2, 5), (3, 6)]

6. collections.namedtuple

namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)
Returns a new subclass of tuple with named fields.

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