# Learning Python — List

Chapter 1: data structure

# Sequences: List, set, Queue, tuple, string

## List :

Methods:

`>>> a = [66.25, 333, 333, 1, 1234.5]>>> print a.count(333), a.count(66.25), a.count('x')2 1 0>>> a.insert(2, -1)>>> a.append(333)>>> a[66.25, 333, -1, 333, 1, 1234.5, 333]>>> a.index(333)1>>> a.remove(333) # only remove a value>>> a[66.25, -1, 333, 1, 1234.5, 333]>>> a.reverse()>>> a[333, 1234.5, 1, 333, -1, 66.25]>>> a.sort()>>> a[-1, 1, 66.25, 333, 333, 1234.5]>>> a.pop()1234.5>>> a[-1, 1, 66.25, 333, 333]>>> a = [-1, 1, 66.25, 333, 333, 1234.5]>>> del a[0]  # del is more flexible>>> a[1, 66.25, 333, 333, 1234.5]>>> del a[2:4]>>> a[1, 66.25, 1234.5]>>> del a[:]>>> a[]pos.sort(key = lambda k:(k[0],k[1])) # sort with the first element in tuple, then if its a tie, sort on the second element, or this can be used for list of list too. people = sorted(people, key=lambda x: (-x[0], x[1])) # reverse first element, and ascending the second elementor insertion_order = sorted(people, key = lambda (h,k): (-h,k))`

List Slices

List slices can also have a third number, representing the step, to include only alternate values in the slice.

`squares = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]print(squares[::2])print(squares[2:8:3])>>>[0, 4, 16, 36, 64][4, 25]>>>`

Negative values can be used in list slicing (and normal list indexing). When negative values are used for the first and second values in a slice (or a normal index), they count from the end of the list.

`squares = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]print(squares[1:-1])>>>[1, 4, 9, 16, 25, 36, 49, 64]>>>`

If a negative value is used for the step, the slice is done backwards.

Using [::-1] as a slice is a common and idiomatic way to reverse a list.

Math operations:

`[3*x for x in [111, 222, 333]]`

If you’re going to be doing lots of array operations, then you will probably find it useful to install Numpy. Then you can use ordinary arithmetic operations element-wise on arrays, and there are lots of useful functions for computing with arrays.

`>>> import numpy>>> a = numpy.array([111,222,333])>>> a * 3array([333, 666, 999])>>> a + 7array([118, 229, 340])>>> numpy.dot(a, a)172494>>> numpy.mean(a), numpy.std(a)(222.0, 90.631120482977593)`

List as Stack: FILO, like stack it in a bottle

`list.insert(end,v) or list.append()list.pop()#example>>> stack = [3, 4, 5]>>> stack.append(6)>>> stack.append(7)>>> stack[3, 4, 5, 6, 7]>>> stack.pop()7>>> stack[3, 4, 5, 6]>>> stack.pop()6>>> stack.pop()5>>> stack[3, 4]`

List as Queue: FIFO

`list.insert(0,Value)list.pop()    `

However, it is not efficient, so we use the package, Queue, include Queue(), LifoQueue(), and PriorityQueue()

`from Queue import *q=Queue.Queue()q.put(1)q.get()`

2. There are three built-in functions that are very useful when used with lists: `filter()`, `map()`, and `reduce()`.

`filter(function, sequence)` returns a sequence for which `function(item)` is true. If sequence is a `str`, `unicode` or `tuple`, the result will be of the same type; otherwise, it is always a `list`.

`>>> def f(x): return x % 3 == 0 or x % 5 == 0...>>> filter(f, range(2, 25)) # use lambda expression lambda x:x%3==0 or x%5==0[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]`

`map(function, sequence)` calls `function(item)` returns a list of the return values of function. To

`>>> def cube(x): return x*x*x...>>> map(cube, range(1, 11))[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]>>> seq = range(8)>>> def add(x, y): return x+y...>>> map(add, seq, seq)[0, 2, 4, 6, 8, 10, 12, 14]`

Map could be replace by a more powerful library: Numpy

`reduce(function, sequence)` returns a single value constructed by calling the binary function function on the first two items of the sequence, then on the result and the next item, and so on.

`>>> def add(x,y): return x+y...>>> reduce(add, range(1, 11))55`

More with the list:

List comprehensions are a useful way of quickly creating lists whose contents obey a simple rule.

Trying to create a list in a very extensive range will result in a MemoryError.

This code shows an example where the list comprehension runs out of memory.

`even = [2*i for i in range(10**100)]>>>MemoryError>>>`

For example, we can do the following:

`squares = [x**2 for x in range(10)]>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y][(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]`

2. Using list as matrix

`>>> matrix = [...     [1, 2, 3, 4],...     [5, 6, 7, 8],...     [9, 10, 11, 12],... ][[row[i] for row in matrix] for i in range(4)] # do a transpose[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]`

In the real world, you should prefer built-in functions to complex flow statements. The `zip()` function would do a great job for this use case:

`>>> zip(*matrix) # to do a transpose, each col become each row[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]`

## Tuple

A tuple consists of a number of values separated by commas. Tuple is immutable, it is just like the list except it uses parenthesis instead of brackets. Tuple can contact mutable elements. for instance:

`>>> t = 12345, 54321, ‘hello!’#Tuples can be created without the parentheses, by just separating the values with commas.>>> t[0]12345>>> t(12345, 54321, ‘hello!’)>>> # Tuples may be nested:... u = t, (1, 2, 3, 4, 5)>>> u((12345, 54321, ‘hello!’), (1, 2, 3, 4, 5))>>> # Tuples are immutable:... t[0] = 88888Traceback (most recent call last):  File "<stdin>", line 1, in <module>TypeError: ‘tuple’ object does not support item assignment>>> # but they can contain mutable objects:... v = ([1, 2, 3], [3, 2, 1])>>> v([1, 2, 3], [3, 2, 1])>>> empty = () # declare empty tuple>>> singleton = 'hello',    # <-- note trailing comma>>> len(empty)0>>> len(singleton)1>>> singleton('hello',)`

Tuples are faster than lists, but they cannot be changed.

## Set

Python also includes a data type for sets. A set is an unordered collection with no duplicate elements. Basic uses eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.

set can have elements of tuple, string, but not list(convert it to tuple),

Here is a brief demonstration:

`>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']>>> fruit = set(basket) or set()          # create a set without duplicates>>> fruitset(['orange', 'pear', 'apple', 'banana'])>>> 'orange' in fruit                 # fast membership testingTrue>>> 'crabgrass' in fruitFalsefruit.add("watermelon")  #add one element>>> # Demonstrate set operations on unique letters from two words...>>> a = set('abracadabra')>>> b = set('alacazam')>>> a                                set(['a', 'r', 'b', 'c', 'd'])>>> a - b                              # letters in a but not in bset(['r', 'd', 'b'])>>> a | b                              # letters in either a or bset(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])>>> a & b                              # letters in both a and bset(['a', 'c'])>>> a ^ b                              # letters in a or b but not bothset(['r', 'd', 'b', 'm', 'z', 'l'])`

# Dictionaries, not sequence

Another useful data type built into Python is the dictionary (see Mapping Types — dict). Unlike sequences, which are indexed by a range of numbers, dictionaries are indexed by keys, which can be any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can’t use lists as keys, since lists can be modified in place using index assignments.

It is best to think of a dictionary as an unordered set of key: value pairs, with the requirement that the keys are unique (within one dictionary). A pair of braces creates an empty dictionary: `{}`.

The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with `del`. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.

The `keys()` method of a dictionary object returns a list of all the keys used in the dictionary, in arbitrary order (if you want it sorted, just apply the `sorted()` function to it). To check whether a single key is in the dictionary, use the `in` keyword.

Here is a small example using a dictionary:

`>>> tel = {'jack': 4098, 'sape': 4139}>>> tel['guido'] = 4127>>> tel{'sape': 4139, 'guido': 4127, 'jack': 4098}>>> tel['jack']4098>>> del tel['sape']>>> tel['irv'] = 4127>>> tel{'guido': 4127, 'irv': 4127, 'jack': 4098}>>> tel.keys()['guido', 'irv', 'jack']>>> 'guido' in telTrue>>> tel = {'guido': 4127, 'irv': 4127, 'jack': 4098}>>> tel{'jack': 4098, 'irv': 4127, 'guido': 4127}>>> tel.keys()['jack', 'irv', 'guido']>>> tel.values()[4098, 4127, 4127]>>> tel.items()[('jack', 4098), ('irv', 4127), ('guido', 4127)]>>> for k,v in tel.items():...     print k,v...jack 4098irv 4127guido 4127#get the value from key>>> tel{'jack': 4098, 'irv': 4127, 'guido': 4127}>>> tel.get("adc",0)0>>> tel{'jack': 4098, 'irv': 4127, 'guido': 4127}>>> tel.get('jack')4098>>>`

The `dict()` constructor builds dictionaries directly from sequences of key-value pairs:

`>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]){'sape': 4139, 'jack': 4098, 'guido': 4127}`

In addition, dict comprehensions can be used to create dictionaries from arbitrary key and value expressions:

`>>> {x: x**2 for x in (2, 4, 6)}{2: 4, 4: 16, 6: 36}`

When the keys are simple strings, it is sometimes easier to specify pairs using keyword arguments:

`>>> dict(sape=4139, guido=4127, jack=4098){'sape': 4139, 'jack': 4098, 'guido': 4127}#create a dictionary from two lists:>>> keys = ['a', 'b', 'c']>>> values = [1, 2, 3]>>> dictionary = dict(zip(keys, values))>>> print(dictionary){'a': 1, 'b': 2, 'c': 3}`

## Looping Techniques

When looping through a sequence, the position index and corresponding value can be retrieved at the same time using the `enumerate()` function.

`>>> for i, v in enumerate(['tic', 'tac', 'toe']): # for list, for loop the dictionary, use d.items() or d.keys(), d.values()...     print i, v...0 tic1 tac2 toe`

To loop over two or more sequences at the same time, the entries can be paired with the `zip()` function.

`>>> questions = ['name', 'quest', 'favorite color']>>> answers = ['lancelot', 'the holy grail', 'blue']>>> for q, a in zip(questions, answers):...     print 'What is your {0}?  It is {1}.'.format(q, a)...What is your name?  It is lancelot.What is your quest?  It is the holy grail.What is your favorite color?  It is blue.`

To loop over a sequence in reverse, first specify the sequence in a forward direction and then call the `reversed()` function.

`>>> for i in reversed(xrange(1,10,2)):...     print i...97531`

To loop over a sequence in sorted order, use the `sorted()` function which returns a new sorted list while leaving the source unaltered.

`>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']>>> for f in sorted(set(basket)): # if we want to eliminate repeats, using set, we sort strings according to alphabeta...     print f...applebananaorangepear`

# String is a Container, but Immutable

A string is a sequence of characters. A character is simply a symbol. For example, the English language has 26 characters. Computers do not deal with characters, they deal with numbers (binary). Even though you may see characters on your screen, internally it is stored and manipulated as a combination of 0’s and 1’s. This conversion of character to a number is called encoding, and the reverse process is decoding. ASCII and Unicode are some of the popular encoding used.

`astring = "Hello world!"astring2 = 'Hello world!'# triple quotes string can extend multiple linesmy_string = """Hello, welcome to           the world of Python"""print(my_string)print("single quotes are ' '")print(len(astring))print(astring.index("o"))print(astring.count("l"))print(astring[3:7]) #slicingprint(astring[3:7:3])print(astring.upper())print(astring.lower())afewwords = astring.split(" ") #splitting>>> my_string = 'programiz'>>> my_string[5] = 'a'...TypeError: 'str' object does not support item assignment#iteratecount = 0for letter in 'Hello World':    if(letter == 'l'):        count += 1print(count,'letters found')`

Like above, python string can be indexed, counted, sliced, sorted, but cant assign new value. What if we want to change a string?

`str = 'cold'str = list(str)str.insert(0,'good ')str = ''.join(str) # ',' or '\n', we can use different way to join themprint(str)#outputgood cold#others: >>> "This will split all words into a list".split()['This', 'will', 'split', 'all', 'words', 'into', 'a', 'list']>>> ' '.join(['This', 'will', 'join', 'all', 'words', 'into', 'a', 'string'])'This will join all words into a string'>>> 'Happy New Year'.find('ew')7>>> 'Happy New Year'.replace('Happy','Brilliant')'Brilliant New Year'`

Another way:

`# enumerate()list_enumerate = list(enumerate(str))print('list(enumerate(str) = ', list_enumerate)#character countprint('len(str) = ', len(str))#outputlist(enumerate(str) =  [(0, 'g'), (1, 'o'), (2, 'o'), (3, 'd'), (4, ' '), (5, 'c'), (6, 'o'), (7, 'l'), (8, 'd')]len(str) =  9`

## String Membership Test

We can test if a sub string exists within a string or not, using the keyword `in`.

`>>> 'a' in 'program'True>>> 'at' not in 'battle'False`

## String operaters

`str1 = 'Hello'str2 ='World!'# using +print('str1 + str2 = ', str1 + str2)# using *print('str1 * 3 =', str1 * 3)#outputstr1 + str2 =  HelloWorld!str1 * 3 = HelloHelloHello`

string formatting

`# using triple quotesprint('''He said, "What's there?"''')# escaping single quotesprint('He said, "What\'s there?"')# escaping double quotesprint("He said, \"What's there?\"")#outputHe said, "What's there?"He said, "What's there?"He said, "What's there?"#formoat# default(implicit) orderdefault_order = "{}, {} and {}".format('John','Bill','Sean')print('\n--- Default Order ---')print(default_order)# order using positional argumentpositional_order = "{1}, {0} and {2}".format('John','Bill','Sean')print('\n--- Positional Order ---')print(positional_order)# order using keyword argumentkeyword_order = "{s}, {b} and {j}".format(j='John',b='Bill',s='Sean')print('\n--- Keyword Order ---')print(keyword_order)#output--- Default Order ---John, Bill and Sean--- Positional Order ---Bill, John and Sean--- Keyword Order ---Sean, Bill and John`

--

--

## More from Li Yin

Founder@sylphai.com. Twitter: liyinscience. Ex AI researcher@ Meta AI. Github:https://github.com/liyin2015.