Python3 Study Notes --- reference http://python3-cookbook.readthedocs.io/zh_CN/latest,

Source: Internet
Author: User
Tags element groups

Python3 Study Notes --- reference http://python3-cookbook.readthedocs.io/zh_CN/latest,
Data structures and algorithms (1)

1.1 The decompression sequence is assigned to multiple variables:

Any sequence (or iteratable object) can be decompressed and assigned to multiple variables through a simple assignment statement. The only premise is that the number of variables must be the same as the number of sequential elements.

>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]>>> name, shares, price, date = data>>> name'ACME'

This method requires the matching of the number of variables and the number of elements in the sequence; otherwise, an exception occurs.

Sample Code:

>>> p = (4, 5)>>> x, y, z = pTraceback (most recent call last):File "<stdin>", line 1, in <module>ValueError: need more than 2 values to unpack

Any placeholder can be used to discard elements:

>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]>>> _, shares, price, _ = data>>> shares50

1.2 decompress and assign an iteration object to multiple variables

>>> record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')>>> name, email, *phone_numbers = record>>> name'Dave'>>> email'dave@example.com'>>> phone_numbers['773-555-1212', '847-555-1212']>>>

It is worth noting thatphone_numbersVariables are always list types, regardless of the number of extracted phone numbers (including 0 ). Therefore, anyphone_numbersNo extra type check is required for variable code to check whether it is a list type.

It is worth noting that the asterisk expression is useful when the iteration element is a sequence of variable long element groups. For example, the following is a sequence of tuples with tags:

records = [    ('foo', 1, 2),    ('bar', 'hello'),    ('foo', 3, 4),]def do_foo(x, y):    print('foo', x, y)def do_bar(s):    print('bar', s)for tag, *args in records:    if tag == 'foo':        do_foo(*args)    elif tag == 'bar':        do_bar(*args)

The asterisks decompression syntax is also useful for string operations, such as string segmentation.

Sample Code:

>>> line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'>>> uname, *fields, homedir, sh = line.split(':')>>> uname'nobody'>>> homedir'/var/empty'>>> sh'/usr/bin/false'>>>

Sometimes, if you want to extract some elements and discard them, you cannot simply use them.*But you can use a common obsolete name, such_Orign(Ignore ).

Sample Code:

>>> record = ('ACME', 50, 123.45, (12, 18, 2012))>>> name, *_, (*_, year) = record>>> name'ACME'>>> year2012>>>

If you are smart enough, you can use this segmentation syntax to skillfully implement recursive algorithms. For example:

1 >>> def sum(items):2 ...     head, *tail = items3 ...     return head + sum(tail) if tail else head4 ...5 >>> sum(items)6 367 >>>

Then, due to language limitations, recursion is not good at Python.

1.3 retain the last N elements

Keep a limited historycollections.dequeShow your skills. For example, the following code performs a simple text match on multiple lines and returns the last N lines of the matching row:

 

from collections import dequedef search(lines, pattern, history=5):    previous_lines = deque(maxlen=history)    for line in lines:        if pattern in line:            yield line, previous_lines        previous_lines.append(line)# Example use on a fileif __name__ == '__main__':    with open(r'../../cookbook/somefile.txt') as f:        for line, prevlines in search(f, 'python', 5):            for pline in prevlines:                print(pline, end='')            print(line, end='')            print('-' * 20)

 

Usedeque(maxlen=N)The constructor creates a queue of a fixed size. When a new element is added and the queue is full, the oldest element is automatically removed.

You can also manually perform this operation on a list (such as adding or deleting a list ). However, the queue solution here will be more elegant and run faster.

More general,dequeClasses can be used in any scenario where you only need a simple queue data structure. If you do not set the maximum queue size, you will get an infinite queue. You can add and pop up elements at both ends of the queue.

Sample Code:

 

>>> q = deque()>>> q.append(1)>>> q.append(2)>>> q.append(3)>>> qdeque([1, 2, 3])>>> q.appendleft(4)>>> qdeque([4, 1, 2, 3])>>> q.pop()3>>> qdeque([4, 1, 2])>>> q.popleft()4

 

The time complexity of inserting or deleting elements at both ends of the queue isO(1), Unlike the list, the time complexity of inserting or deleting elements at the beginning of the List isO(N).

1.4 search for n elements at the maximum or minimum

The heapq module has two functions:nlargest()Andnsmallest()This problem can be solved perfectly.

import heapqnums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]print(heapq.nlargest(3, nums)) # Prints [42, 37, 23]print(heapq.nsmallest(3, nums)) # Prints [-4, 1, 2]

Both functions can accept a keyword parameter for more complex data structures:

 1 portfolio = [ 2     {'name': 'IBM', 'shares': 100, 'price': 91.1}, 3     {'name': 'AAPL', 'shares': 50, 'price': 543.22}, 4     {'name': 'FB', 'shares': 200, 'price': 21.09}, 5     {'name': 'HPQ', 'shares': 35, 'price': 31.75}, 6     {'name': 'YHOO', 'shares': 45, 'price': 16.35}, 7     {'name': 'ACME', 'shares': 75, 'price': 115.65} 8 ] 9 cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price'])10 expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price'])
View Code

If you want to find the minimum or maximum N elements in a set, and N is smaller than the number of set elements, these functions provide good performance. In the underlying implementation, the Set Data is first sorted by heap and then put into a list:

>>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]>>> import heapq>>> heap = list(nums)>>> heapq.heapify(heap)>>> heap[-4, 2, 1, 23, 7, 2, 18, 23, 42, 37, 8]>>>

The most important feature of the heap data structure isheap[0]Always the smallest element. And the remaining elements can be easily calledheapq.heappop()This method first pops up the first element, and then replaces the pop-up element with the smallest element (the time complexity of this operation is only O (log N ), N is the heap size ). For example, if you want to find the smallest three elements, you can do this:

>>> heapq.heappop(heap)-4>>> heapq.heappop(heap)1>>> heapq.heappop(heap)2

When the number of elements to be searched is relatively small, the functionnlargest()Andnsmallest()Is very suitable. If you only want to find the unique minimum or maximum (N = 1) element, usemin()Andmax()The function is faster. Similarly, if the size of N is close to that of the set, it is usually faster to sort the set first and then use the slice operation (sorted(items)[:N]Orsorted(items)[-N:]). Use the function properlynlargest()Andnsmallest()To make full use of their advantages (if N is close to the set size, it would be better to use sorting operations ).

1.5 implement a priority queue

Use the following classesheapqThe module implements a simple priority queue:

 1 import heapq 2  3 class PriorityQueue: 4     def __init__(self): 5         self._queue = [] 6         self._index = 0 7  8     def push(self, item, priority): 9         heapq.heappush(self._queue, (-priority, self._index, item))10         self._index += 111 12     def pop(self):13         return heapq.heappop(self._queue)[-1]

 

>>> class Item:...     def __init__(self, name):...         self.name = name...     def __repr__(self):...         return 'Item({!r})'.format(self.name)...>>> q = PriorityQueue()>>> q.push(Item('foo'), 1)>>> q.push(Item('bar'), 5)>>> q.push(Item('spam'), 4)>>> q.push(Item('grok'), 1)>>> q.pop()Item('bar')>>> q.pop()Item('spam')>>> q.pop()Item('foo')>>> q.pop()Item('grok')>>>

 heappop()The function always returns the "smallest" element, which is the key to ensure that the queue pop operation returns the correct element. In addition, since the time complexity of push and pop operations is O (log N), N is the size of the heap, so even if N is very large, they still run fast.

In the code above, the queue contains(-priority, index, item). The purpose of a negative priority is to sort elements by priority from high to low. This is the opposite of the normal heap sorting by priority from low to high.

indexVariables are used to ensure the correct sorting of elements with the same priority. By saving an ever-increasingindexSubscript variables ensure that elements are sorted in the order they are inserted. And,indexVariables also play an important role in comparing elements with the same priority.

To clarify this, first assumeItemInstances do not support sorting:

1 >>> a = Item('foo')2 >>> b = Item('bar')3 >>> a < b4 Traceback (most recent call last):5 File "<stdin>", line 1, in <module>6 TypeError: unorderable types: Item() < Item()7 >>>

 

If you use tuples(priority, item)The two elements can be compared as long as their priorities are different. However, if the two elements have the same priority, the comparison operation will have the same error as before:

 1 >>> a = (1, Item('foo')) 2 >>> b = (5, Item('bar')) 3 >>> a < b 4 True 5 >>> c = (1, Item('grok')) 6 >>> a < c 7 Traceback (most recent call last): 8 File "<stdin>", line 1, in <module> 9 TypeError: unorderable types: Item() < Item()10 >>>

 

By introducing anotherindexVariable composition triple(priority, index, item)To avoid the above errors, because there cannot be two elements with the sameindexValue. When Python compares tuples, if the previous comparison can determine the result, the subsequent comparison operation will not happen:

>>> a = (1, 0, Item('foo'))>>> b = (5, 1, Item('bar'))>>> c = (1, 2, Item('grok'))>>> a < bTrue>>> a < cTrue>>>

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.