Strings and common data structures

Using strings

The second world war led to the birth of the modern electronic computer, the original idea is very simple, is to use the computer to calculate the ballistic missile, so just the time of the birth of the computer, the computer information processing mainly, and the world’s first electronic computer ENIAC to about 5000 times per second floating point arithmetic. Over time, while numeric manipulation is still one of the most important tasks in a computer’s daily routine, today’s computers deal with more data in the form of text information, and Python represents text information in a way we talked about a long time ago, as strings. The so-calledstring, is a finite sequence of zero or more characters.

We can see the use of strings in the following code.

def main():
    str1 = 'hello, world! '
    The len function calculates the length of the string
    print(len(str1))  # 13
    Get an uppercase copy of the string
    print(str1.capitalize())  # Hello, world!
    Get a copy of the string in uppercase
    print(str1.upper())  # HELLO, WORLD!
    # Find the substring position in the string
    print(str1.find('or'))  # 8
    print(str1.find('shit'))  # 1
    # Similar to find, but an exception is raised when no substring is found
    # print(str1.index('or'))
    # print(str1.index('shit'))
    Check if the string begins with the specified string
    print(str1.startswith('He'))  # False
    print(str1.startswith('hel'))  # True
    Check if the string ends with the specified string
    print(str1.endswith('! '))  # True
    # centers the string with the specified width and fills the sides with the specified characters
    print(str1.center(50, The '*'))
    # place the string to the right of the specified width and the left to fill the specified character
    print(str1.rjust(50, ' '))
    str2 = 'abc123456'
    # Retrieve character from string at specified position (subscript operation)
    print(str2[2])  # c
    # string slice (from the specified start index to the specified end index)
    print(str2[2:5])  # c12
    print(str2[2:])  # c123456
    print(str2[2::2])  # c246
    print(str2[::2])  # ac246
    print(str2[::-1])  # 654321cba
    print(str2[-3:-1])  # 45
    Check if the string is composed of numbers
    print(str2.isdigit())  # False
    Check if the string is composed of letters
    print(str2.isalpha())  # False
    Check if the string is composed of numbers and letters
    print(str2.isalnum())  # True
    str3 = ' [email protected] '
    print(str3)
    Get a copy of the trim left and right Spaces of the string
    print(str3.strip())


if __name__ == '__main__':
    main()Copy the code

In addition to strings, Python has many types of built-in data structures. Most of the time, if you want to store and manipulate data in a program, you can use existing data structures. The most common ones include lists, tuples, collections, and dictionaries.

Use the list

The following code demonstrates how to define a list, access list elements using subscripts, and add and remove elements.

def main():
    list1 = [1, 3, 5, 7, 100]
    print(list1)
    list2 = ['hello'] * 5
    print(list2)
    # calculate list length (number of elements)
    print(len(list1))
    # index operation
    print(list1[0])
    print(list1[4])
    # print(list1[5]) # IndexError: list index out of range
    print(list1[-1])
    print(list1[-3])
    list1[2] = 300
    print(list1)
    # add element
    list1.append(200)
    list1.insert(1, 400)
    list1 += [1000, 2000]
    print(list1)
    print(len(list1))
    # delete element
    list1.remove(3)
    if 1234 in list1:
        list1.remove(1234)
    del list1[0]
    print(list1)
    Clear list elements
    list1.clear()
    print(list1)


if __name__ == '__main__':
    main()Copy the code

Like strings, lists can also be sliced, which allows you to copy a list or create a new list by taking parts out of the list, as shown below.

def main():
    fruits = ['grape'.'apple'.'strawberry'.'waxberry']
	fruits += ['pitaya'.'pear'.'mango']
	Loop over the list elements
    for fruit in fruits:
        print(fruit.title(), end=' ')
    print(a)# list slice
    fruits2 = fruits[1:4]
    print(fruits2)
    # fruit3 = fruits # No copies of the list just create new references
    The list can be copied by a full slice operation
    fruits3 = fruits[:]
    print(fruits3)
    fruits4 = fruits[-3:-1]
    print(fruits4)
    You can use reverse slicing to get a copy of the inverted list
    fruits5 = fruits[::-1]
    print(fruits5)


if __name__ == '__main__':
    main()Copy the code

The following code implements sorting the list.

def main():
    list1 = ['orange'.'apple'.'zoo'.'internationalization'.'blueberry']
    list2 = sorted(list1)
    The # sorted function returns a sorted copy of the list without modifying the list passed in
    The sorted function should be designed to have as few side effects as possible
    list3 = sorted(list1, reverse=True)
    The key keyword argument specifies that the string is sorted by length rather than the default alphabetical order
    list4 = sorted(list1, key=len)
    print(list1)
    print(list2)
    print(list3)
    print(list4)
    Sort the list object directly
    list1.sort(reverse=True)
    print(list1)


if __name__ == '__main__':
    main()Copy the code

We can also use the generative syntax of lists to create lists, as shown below.

import sys


def main():
    f = [x for x in range(1, 10)]
    print(f)
    f = [x + y for x in 'ABCDE' for y in '1234567']
    print(f)
    Create a list container using the list generative expression syntax
    After creating a list with this syntax, the elements are ready so it takes a lot of memory
    f = [x ** 2 for x in range(1, 1000)]
    print(sys.getsizeof(f))  # check the number of bytes used by the object
    print(f)
    Note that the following code creates not a list but a generator object
    The generator can fetch data but it does not take up extra space to store data
    # Get data internally every time you need it (takes extra time)
    f = (x ** 2 for x in range(1, 1000))
    print(sys.getsizeof(f))  Does not take up space to store data compared to a generative generator
    print(f)
    for val in f:
        print(val)


if __name__ == '__main__':
    main()Copy the code

In addition to the generator syntax mentioned above, there is another way to define generators in Python, which is to use the yield keyword to transform an ordinary function into a generator function. The following code demonstrates how to implement a generator that generates a Fibonacci sequence. The Fibonacci sequence can be defined recursively as follows:

def fib(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
        yield a


def main():
    for val in fib(20):
        print(val)


if __name__ == '__main__':
    main()Copy the code

Use a tuple

Python tuples are similar to lists, except that the elements of a tuple cannot be modified, and we have used tuples more than once in the previous code. As the name implies, we combine multiple elements together to form a tuple, so it can hold multiple pieces of data just like a list. The following code demonstrates how to define and use tuples.

def main():
    # define tuples
    t = ('LuoHao', 38, True, 'Chengdu, Sichuan')
    print(t)
    Get the element in the tuple
    print(t[0])
    print(t[3])
    Iterate over the values in the tuple
    for member in t:
        print(member)
    # reassign a tuple
    # t[0] = 'kinghammer' # TypeError
    # the variable t rereferences the new tuple. The original tuple will be garbage collected
    t = (King's Sledgehammer, 20, True, Kunming, Yunnan province)
    print(t)
    # Convert tuples to lists
    person = list(t)
    print(person)
    A list can change its elements
    person[0] = Bruce Lee
    person[1] = 25
    print(person)
    # Convert lists to tuples
    fruits_list = ['apple'.'banana'.'orange']
    fruits_tuple = tuple(fruits_list)
    print(fruits_tuple)


if __name__ == '__main__':
    main()Copy the code

The question is, why do we need tuples when we already have lists?

  1. Can’t modify the elements in the tuple, in fact, in our project, especially a multithreaded environment (below) may prefer to use is the same object (state on the one hand, because the object cannot be modified, so can avoid the resulting unnecessary bugs, simple said is an immutable object than mutable objects more easy to maintain; On the other hand, since no thread can modify the internal state of an immutable object, an immutable object is automatically thread-safe, thus eliminating the overhead of handling synchronization. An immutable object can be easily shared. So the conclusion is: if you don’t need to add, delete, or modify elements, you can use tuples, but if a method returns multiple values, you can use tuples.
  2. Tuples are better than lists in both creation time and space. It is easy to use the sys module’s getSizeof function to check how much memory is occupied by tuples and lists that store the same elements. We can also analyze the timeit takes to create tuples and lists of the same content using the magic %timeit directive in ipython, as shown below on my macOS.

Using the collection

Collections in Python are the same as collections in mathematics. There are no duplicate elements, and you can do intersection, union, difference, and so on.

def main():
    set1 = {1, 2, 3, 3, 3, 2}
    print(set1)
    print('Length =', len(set1))
    set2 = set(range(1, 10))
    print(set2)
    set1.add(4)
    set1.add(5)
    set2.update([11, 12])
    print(set1)
    print(set2)
    set2.discard(5)
    # remove raises KeyError if the element does not exist
    if 4 in set2:
        set2.remove(4)
    print(set2)
    Pass through the collection container
    for elem in set2:
        print(elem ** 2, end=' ')
    print(a)# convert a tuple to a set
    set3 = set(1, 2, 3, 3, 2, 1)print(set3.pop())
    print(set3)
    # Set of intersection, union, difference, symmetry difference operation
    print(set1 & set2)
    # print(set1.intersection(set2))
    print(set1 | set2)
    # print(set1.union(set2))
    print(set1 - set2)
    # print(set1.difference(set2))
    print(set1 ^ set2)
    # print(set1.symmetric_difference(set2))
    # Determine subsets and supersets
    print(set2 < =set1)
    # print(set2.issubset(set1))
    print(set3 < =set1)
    # print(set3.issubset(set1))
    print(set1 > =set2)
    # print(set1.issuperset(set2))
    print(set1 > =set3)
    # print(set1.issuperset(set3))


if __name__ == '__main__':
    main()Copy the code

Description: Python allows special methods for customizing operators for certain types or data structures (which will be covered in a later section). In the above code, we can either call the collection object’s methods or use the corresponding operators when we perform operations on collections. The & operator, for example, works the same as the intersection method, but using the operator makes code more intuitive.

Use a dictionary

A dictionary is another mutable container model, similar to the dictionary we use in our daily life. It can store objects of any type. Unlike lists and collections, each element of a dictionary is a “key-value pair” consisting of a key and a value, separated by a colon. The following code demonstrates how to define and use a dictionary.

def main():
    scores = {'LuoHao': 95, 'Bai Yuanfang': 78, Dee Renjie: 82}
    The key can be used to obtain the corresponding value in the dictionary
    print(scores['LuoHao'])
    print(scores[Dee Renjie])
    The dictionary is traversed by the keys.
    for elem in scores:
        print('%s\t--->\t%d' % (elem, scores[elem]))
    Update elements in the dictionary
    scores['Bai Yuanfang'] = 65
    scores['Zhuge King Lang'] = 71 scores. Update (score =67, score =85)print(scores)
    if 'Wu Zetian' in scores:
        print(scores['Wu Zetian'])
    print(scores.get('Wu Zetian'))
    The # get method also gets the corresponding value by key but can set the default value
    print(scores.get('Wu Zetian', 60))
    Delete the element from the dictionary
    print(scores.popitem())
    print(scores.popitem())
    print(scores.pop('LuoHao', 100))
    # Empty the dictionary
    scores.clear()
    print(scores)


if __name__ == '__main__':
    main()Copy the code

practice

Exercise 1: Display running text on the screen

import os
import time


def main():
    content = 'Beijing welcomes you to open the world for you ………… '
    while True:
        Clean up the output on the screen
        os.system('cls')  # os.system('clear')
        print(content)
        Sleep for 200 millisecondsTime.sleep (0.2) content = content[1:] + content[0]if __name__ == '__main__':
    main()Copy the code

Exercise 2: Design a function to generate a captcha of specified length, consisting of upper and lower case letters and numbers.

import random


def generate_code(code_len=4):
    """Generate a captcha of specified length :param code_len: The length of the captcha (4 characters by default) :return: a random captcha composed of upper and lower case letters and numbers"""
    all_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    last_pos = len(all_chars) - 1
    code = ' '
    for _ in range(code_len):
        index = random.randint(0, last_pos)
        code += all_chars[index]
    return codeCopy the code

Exercise 3: Design a function that returns the suffix of a given filename.

def get_suffix(filename, has_dot=False):
    """Get the filename extension :param filename: filename: param has_dot: does the return suffix need to be dotted :return: filename extension"""
    pos = filename.rfind('. ')
    if 0 < pos < len(filename) - 1:
        index = pos if has_dot else pos + 1
        return filename[index:]
    else:
        return ' 'Copy the code

Exercise 4: Design a function to return the values of the largest and second largest elements in the passed list.

def max2(x):
    m1, m2 = (x[0], x[1]) if x[0] > x[1] else (x[1], x[0])
    for index in range(2, len(x)):
        if x[index] > m1:
            m2 = m1
            m1 = x[index]
        elif x[index] > m2:
            m2 = x[index]
    return m1, m2Copy the code

Exercise 5: Calculate the number of days in a given year

def is_leap_year(year):
    ""Param year: year: return: returns True for leap year: returns False for common year""
    returnyear % 4 == 0 and year % 100 ! = 0 or year % 400 == 0 def which_day(year, month, date):"""Param year: year: param month: month: param date: day :return: day"""
    days_of_month = [
        [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
        [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    ][is_leap_year(year)]
    total = 0
    for index in range(month - 1):
        total += days_of_month[index]
    return total + date


def main():
    print(which_day(1980, 11, 28))
    print(which_day(1981, 12, 31))
    print(which_day(2018, 1, 1))
    print(which_day(2016, 3, 1))


if __name__ == '__main__':
    main()Copy the code

Exercise 6: Printing Yang Hui triangle.

def main():
    num = int(input('Number of rows: '))
    yh = [[]] * num
    for row in range(len(yh)):
        yh[row] = [None] * (row + 1)
        for col in range(len(yh[row])):
            if col == 0 or col == row:
                yh[row][col] = 1
            else:
                yh[row][col] = yh[row - 1][col] + yh[row - 1][col - 1]
            print(yh[row][col], end='\t')
        print(a)if __name__ == '__main__':
    main()Copy the code

Integrated case

Case 1: Bicolor ball number selection

from random import randrange, randint, sample


def display(balls):
    """Output the bicolor numbers in the list"""
    for index, ball in enumerate(balls):
        if index == len(balls) - 1:
            print('|', end=' ')
        print('%02d' % ball, end=' ')
    print()


def random_select():
    """Pick a group of numbers at random."""
    red_balls = [x for x in range(1, 34)]
    selected_balls = []
    selected_balls = sample(red_balls, 6)
    selected_balls.sort()
    selected_balls.append(randint(1, 16))
    return selected_balls


def main():
    n = int(input('Machine select a few notes:'))
    for _ in range(n):
        display(random_select())


if __name__ == '__main__':
    main()Copy the code

Note: The sample function of the random module is used above to select n non-repeating elements from the list.

Integrated case 2: The Joseph ring problem

"""The lucky christians have 15 15 christians and non-christians in distress at sea, in order to let some people live to the 15 people throw into the sea, there is someone think of a way to is all in a circle, by someone started to count off from 1, report to 9 people are thrown into the sea, then from 1 started to count off behind him, Nine people continue to throw into the sea until 15 people are gone. By the grace of God, all 15 Christians survived. Ask these people how they first stood, which positions were Christian and which positions were non-Christian. """


def main():
    persons = [True] * 30
    counter, index, number = 0, 0, 0
    while counter < 15:
        if persons[index]:
            number += 1
            if number == 9:
                persons[index] = False
                counter += 1
                number = 0
        index += 1
        index %= 30
    for person in persons:
        print('base' if person else 'not', end=' ')


if __name__ == '__main__':
    main()
Copy the code

Integrated case 3: Tic-Tac-toe game

import os


def print_board(board):
    print(board['TL'] + '|' + board['TM'] + '|' + board['TR'])
    print('- + - + -)
    print(board['ML'] + '|' + board['MM'] + '|' + board['MR'])
    print('- + - + -)
    print(board['BL'] + '|' + board['BM'] + '|' + board['BR'])


def main():
    init_board = {
        'TL': ' '.'TM': ' '.'TR': ' '.'ML': ' '.'MM': ' '.'MR': ' '.'BL': ' '.'BM': ' '.'BR': ' '
    }
    begin = True
    while begin:
        curr_board = init_board.copy()
        begin = False
        turn = 'x'
        counter = 0
        os.system('clear')
        print_board(curr_board)
        while counter < 9:
            move = input('It's %s's turn to move, please enter position:' % turn)
            if curr_board[move] == ' ':
                counter += 1
                curr_board[move] = turn
                if turn == 'x':
                    turn = 'o'
                else:
                    turn = 'x'
            os.system('clear')
            print_board(curr_board)
        choice = input('Another game? (yes|no)')
        begin = choice == 'yes'


if __name__ == '__main__':
    main()Copy the code

Note: This last example comes from “Getting Started with Python programming: Automating Tedious Tasks” (a great book for anyone with a programming background who wants to quickly use Python to automate everyday tasks), with a few tweaks to the code.