ZetCode-Python-教程-二-

ZetCode Python 教程(二)

原文:ZetCode

协议:CC BY-NC-SA 4.0

PrettyTable 教程

原文: http://zetcode.com/python/prettytable/

PrettyTable 教程展示了如何使用 Python PrettyTable 模块在 Python 中生成 ASCII 表。 在本教程中,我们使用PTable模块,该模块是原始 PrettyTable 库的分支。

PrettyTable

PrettyTable 是用于生成简单 ASCII 表的 Python 库。 它的灵感来自 PostgreSQL shell psql中使用的 ASCII 表。 我们可以控制表格的许多方面,例如列填充的宽度,文本的对齐方式或表格边框。 我们可以对数据进行排序。

我们还可以选择在最终输出中将显示哪些列和行。 PrettyTable 可以从 CSV,HTML 或数据库游标读取数据,并以 ASCII 或 HTML 输出数据。

PrettyTable 安装

$ sudo pip3 install PTable

我们使用pip3工具安装 PrettyTable。

生成 PrettyTable

可以使用add_row()add_column()方法创建表。

create_by_row.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable()

x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]

x.add_row(["Adelaide", 1295, 1158259, 600.5])
x.add_row(["Brisbane", 5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print(x)

该示例使用add_row()方法创建一个 PrettyTable。

from prettytable import PrettyTable

从模块中,我们导入PrettyTable

x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]

我们设置标题名称。

x.add_row(["Adelaide", 1295, 1158259, 600.5])
x.add_row(["Brisbane", 5905, 1857594, 1146.4])

这些行通过add_row()添加到表中。

print(x)

最后,我们将表格打印到控制台。

$ ./create_by_row.py 
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
|  Adelaide | 1295 |  1158259   |      600.5      |
|  Brisbane | 5905 |  1857594   |      1146.4     |
|   Darwin  | 112  |   120900   |      1714.7     |
|   Hobart  | 1357 |   205556   |      619.5      |
|   Sydney  | 2058 |  4336374   |      1214.8     |
| Melbourne | 1566 |  3806092   |      646.9      |
|   Perth   | 5386 |  1554769   |      869.4      |
+-----------+------+------------+-----------------+

这是输出。

在下一个示例中,我们使用add_column()方法创建相同的表。

create_by_column.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable()

column_names = ["City name", "Area", "Population", "Annual Rainfall"]

x.add_column(column_names[0], ["Adelaide", "Brisbane", "Darwin", 
    "Hobart", "Sydney", "Melbourne", "Perth"])
x.add_column(column_names[1], [1295, 5905, 112, 1357, 2058, 1566, 5386 ])  
x.add_column(column_names[2], [1158259, 1857594, 120900, 205556, 4336374, 
    3806092, 1554769])  
x.add_column(column_names[3], [600.5, 1146.4, 1714.7, 619.5, 1214.8, 
    646.9, 869.4])

print(x)

列名是add_column()方法的第一个参数。

PrettyTable 删除行

使用del_row()可以删除特定的行。 该方法获取要删除的行的索引。 请注意,索引从零开始。

delete_rows.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable()

x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]

x.add_row(["Adelaide", 1295, 1158259, 600.5])
x.add_row(["Brisbane", 5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

x.del_row(6)
x.del_row(5)
x.del_row(4)
x.del_row(3)

print(x)

在示例中,我们删除最后四行。

$ ./delete_rows.py 
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
|  Adelaide | 1295 |  1158259   |      600.5      |
|  Brisbane | 5905 |  1857594   |      1146.4     |
|   Darwin  | 112  |   120900   |      1714.7     |
+-----------+------+------------+-----------------+

前三行保留在输出中。

PrettyTable 清除数据

clear_rows()方法从表中删除所有行,但保留当前的列名。 clear()方法清除行名和列名。

clear_rows.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable()

x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]

x.add_row(["Adelaide", 1295, 1158259, 600.5])
x.add_row(["Brisbane", 5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

x.clear_rows()
print(x)

该示例清除表中的所有行。

$ ./clear_rows.py 
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
+-----------+------+------------+-----------------+

这是示例的输出。 该表的标题不会被删除。

从 CSV 生成 PrettyTable

from_csv()方法可用于从 CSV 数据生成 PrettyTable。

data.csv

"City name", "Area", "Population", "Annual Rainfall"
"Adelaide", 1295, 1158259, 600.5
"Brisbane", 5905, 1857594, 1146.4
"Darwin", 112, 120900, 1714.7
"Hobart", 1357, 205556, 619.5
"Sydney", 2058, 4336374, 1214.8
"Melbourne", 1566, 3806092, 646.9
"Perth", 5386, 1554769, 869.4

data.csv包含用逗号分隔的数据。 请注意,第一行由表列名称组成。

read_from_csv.py

#!/usr/bin/python3

from prettytable import from_csv

with open("data.csv", "r") as fp: 
    x = from_csv(fp)

print(x)

该示例从data.csv读取数据,并从中生成带有from_csv()的 PrettyTable。

从数据库游标生成 PrettyTable

from_db_cursor()方法从数据库游标生成 PrettyTable。

cities.sql

DROP TABLE IF EXISTS Cities;

CREATE TABLE Cities(Id INTEGER PRIMARY KEY, Name TEXT, Area INTEGER, 
    Population INTEGER, Rainfall REAL);

INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Adelaide", 1295, 1158259, 600.5);
INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Brisbane", 5905, 1857594, 1146.4);
INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Darwin", 112, 120900, 1714.7);
INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Hobart", 1357, 205556, 619.5);
INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Sydney", 2058, 4336374, 1214.8);
INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Melbourne", 1566, 3806092, 646.9);
INSERT INTO Cities(Name, Area, Population, Rainfall) VALUES("Perth", 5386, 1554769, 869.4);

这是一个 SQL 脚本,用于在 SQLite 数据库中创建Cities表。

$ sqlite3 data.db 
sqlite> .read cities.sql 
sqlite> SELECT * FROM Cities;
Id          Name        Area        Population  Rainfall  
----------  ----------  ----------  ----------  ----------
1           Adelaide    1295        1158259     600.5     
2           Brisbane    5905        1857594     1146.4    
3           Darwin      112         120900      1714.7    
4           Hobart      1357        205556      619.5     
5           Sydney      2058        4336374     1214.8    
6           Melbourne   1566        3806092     646.9     
7           Perth       5386        1554769     869.4  

我们阅读了cities.sql脚本,该脚本生成数据库表。

read_from_cursor.py

#!/usr/bin/python3

import sqlite3 as lite
from prettytable import from_db_cursor

con = lite.connect('data.db')

with con:

    cur = con.cursor()    
    cur.execute('SELECT * FROM Cities')   

    x = from_db_cursor(cur) 

print(x)

在代码示例中,我们连接到data.db数据库并从Cities表中选择所有数据。 我们使用from_db_cursor()方法从游标生成一个 PrettyTable。

从 HTML 生成 PrettyTable

from_html()从一串 HTML 代码生成一个 PrettyTables 列表。 HTML 中的每个<table>都成为一个 PrettyTable 对象。 from_html_one()从仅包含单个<table>的 HTML 代码字符串中生成 PrettyTable。

data.html

<html>
    <body>
        <table>
            <tr>
                <th>City name</th>
                <th>Area</th>
                <th>Population</th>
                <th>Annual Rainfall</th>
            </tr>
            <tr>
                <td>Adelaide</td>
                <td>1295</td>
                <td>1158259</td>
                <td>600.5</td>
            </tr>
            <tr>
                <td>Brisbane</td>
                <td>5905</td>
                <td>1857594</td>
                <td>1146.4</td>
            </tr>
            <tr>
                <td>Darwin</td>
                <td>112</td>
                <td>120900</td>
                <td>1714.7</td>
            </tr>
            <tr>
                <td>Hobart</td>
                <td>1357</td>
                <td>205556</td>
                <td>619.5</td>
            </tr>
            <tr>
                <td>Sydney</td>
                <td>2058</td>
                <td>4336374</td>
                <td>1214.8</td>
            </tr>
            <tr>
                <td>Melbourne</td>
                <td>1566</td>
                <td>3806092</td>
                <td>646.9</td>
            </tr>
            <tr>
                <td>Perth</td>
                <td>5386</td>
                <td>1554769</td>
                <td>869.4</td>
            </tr>
        </table>
    </body>
</html>

在示例中,我们使用此 HTML 文件。

read_from_html.py

#!/usr/bin/python3

from prettytable import from_html_one

with open("data.html", "r") as fp: 
    html = fp.read()

x = from_html_one(html)
print(x)

该示例从data.html文件中读取数据,并使用from_html_one()方法生成一个 PrettyTable。

排序数据

使用sortby属性,我们将指定要排序的列。 reversesort属性控制排序的方向(升序还是降序)。

sorting.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable()
x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]

x.add_row(["Adelaide", 1295, 1158259, 600.5])
x.add_row(["Brisbane", 5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print("Table sorted by population:")
x.sortby = "Population"
print(x)

print()

print("Table sorted by city in descendig order:")
x.sortby = "City name"
x.reversesort = True
print(x)

在示例中,我们对表的数据进行排序。

print("Table sorted by population:")
x.sortby = "Population"

首先,我们按总体升序对数据进行排序。

x.sortby = "City name"
x.reversesort = True

然后,我们按照城市名称的降序对数据进行排序。

$ ./sorting.py 
Table sorted by population:
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
|   Darwin  | 112  |   120900   |      1714.7     |
|   Hobart  | 1357 |   205556   |      619.5      |
|  Adelaide | 1295 |  1158259   |      600.5      |
|   Perth   | 5386 |  1554769   |      869.4      |
|  Brisbane | 5905 |  1857594   |      1146.4     |
| Melbourne | 1566 |  3806092   |      646.9      |
|   Sydney  | 2058 |  4336374   |      1214.8     |
+-----------+------+------------+-----------------+

Table sorted by city in descendig order:
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
|   Sydney  | 2058 |  4336374   |      1214.8     |
|   Perth   | 5386 |  1554769   |      869.4      |
| Melbourne | 1566 |  3806092   |      646.9      |
|   Hobart  | 1357 |   205556   |      619.5      |
|   Darwin  | 112  |   120900   |      1714.7     |
|  Brisbane | 5905 |  1857594   |      1146.4     |
|  Adelaide | 1295 |  1158259   |      600.5      |
+-----------+------+------------+-----------------+

这是输出。

数据对齐

align属性控制字段的对齐方式。 其可能的值为lcr

alignment.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable()

x.field_names = ["City name", "Area", "Population", "Annual Rainfall"]

x.align["City name"] = "l"
x.align["Area"] = "r"
x.align["Annual Rainfall"] = "r"

x.add_row(["Adelaide", 1295, 1158259, 600.5])
x.add_row(["Brisbane", 5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print(x)

该代码示例在表格列中对齐数据。

x.align["City name"] = "l"

我们将City name列中的字段对齐到左侧。

x.align["Area"] = "r"
x.align["Annual Rainfall"] = "r"

我们将AreaAnnual Rainfall中的字段右对齐。

$ ./alignment.py 
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
| Adelaide  | 1295 |  1158259   |           600.5 |
| Brisbane  | 5905 |  1857594   |          1146.4 |
| Darwin    |  112 |   120900   |          1714.7 |
| Hobart    | 1357 |   205556   |           619.5 |
| Sydney    | 2058 |  4336374   |          1214.8 |
| Melbourne | 1566 |  3806092   |           646.9 |
| Perth     | 5386 |  1554769   |           869.4 |
+-----------+------+------------+-----------------+

这是输出。

HTML 输出

get_html_string()从 PrettyTable 生成 HTML 输出。

html_output.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"])

x.add_row(["Adelaide",1295, 1158259, 600.5])
x.add_row(["Brisbane",5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print(x.get_html_string())

该示例将 HTML 表中的数据打印到控制台。

get_string方法

get_string()方法返回当前状态下的表的字符串表示形式。 它有几个选项可以控制表格的显示方式。

显示标题

使用title参数,我们可以在输出中包括表标题。

table_title.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"])

x.add_row(["Adelaide",1295, 1158259, 600.5])
x.add_row(["Brisbane",5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print(x.get_string(title="Australian cities"))

该示例创建一个带标题的 PrettyTable。

$ ./table_title.py 
+-------------------------------------------------+
|                Australian cities                |
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
|  Adelaide | 1295 |  1158259   |      600.5      |
|  Brisbane | 5905 |  1857594   |      1146.4     |
|   Darwin  | 112  |   120900   |      1714.7     |
|   Hobart  | 1357 |   205556   |      619.5      |
|   Sydney  | 2058 |  4336374   |      1214.8     |
| Melbourne | 1566 |  3806092   |      646.9      |
|   Perth   | 5386 |  1554769   |      869.4      |
+-----------+------+------------+-----------------+

这是输出。

选择列

使用fields选项,我们可以选择将要显示的列。

select_columns.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"])

x.add_row(["Adelaide",1295, 1158259, 600.5])
x.add_row(["Brisbane",5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print(x.get_string(fields=["City name", "Population"]))

在该示例中,我们仅显示City namePopulation列。

$ ./select_columns.py 
+-----------+------------+
| City name | Population |
+-----------+------------+
|  Adelaide |  1158259   |
|  Brisbane |  1857594   |
|   Darwin  |   120900   |
|   Hobart  |   205556   |
|   Sydney  |  4336374   |
| Melbourne |  3806092   |
|   Perth   |  1554769   |
+-----------+------------+

选择行

使用startend参数,我们可以选择在输出中显示哪些行。

select_rows.py

#!/usr/bin/python3

from prettytable import PrettyTable

x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"])

x.add_row(["Adelaide",1295, 1158259, 600.5])
x.add_row(["Brisbane",5905, 1857594, 1146.4])
x.add_row(["Darwin", 112, 120900, 1714.7])
x.add_row(["Hobart", 1357, 205556, 619.5])
x.add_row(["Sydney", 2058, 4336374, 1214.8])
x.add_row(["Melbourne", 1566, 3806092, 646.9])
x.add_row(["Perth", 5386, 1554769, 869.4])

print(x.get_string(start=1, end=4))

在示例中,我们在输出中仅包括三行。

$ ./select_rows.py 
+-----------+------+------------+-----------------+
| City name | Area | Population | Annual Rainfall |
+-----------+------+------------+-----------------+
|  Brisbane | 5905 |  1857594   |      1146.4     |
|   Darwin  | 112  |   120900   |      1714.7     |
|   Hobart  | 1357 |   205556   |      619.5      |
+-----------+------+------------+-----------------+

这是示例的输出。

在本教程中,我们已使用 PrettyTable 库在 Python 中生成 ASCII 表。

您可能也会对以下相关教程感兴趣: Python CSV 教程Tkinter 教程SymPy 教程Python Pillow 教程Matplotlib 教程Python 教程

BeautifulSoup 教程

原文: http://zetcode.com/python/beautifulsoup/

BeautifulSoup 教程是 BeautifulSoup Python 库的入门教程。 这些示例查找标签,遍历文档树,修改文档和刮取网页。

BeautifulSoup

BeautifulSoup 是用于解析 HTML 和 XML 文档的 Python 库。 它通常用于网页抓取。 BeautifulSoup 将复杂的 HTML 文档转换为复杂的 Python 对象树,例如标记,可导航字符串或注释。

安装 BeautifulSoup

我们使用pip3命令安装必要的模块。

$ sudo pip3 install lxml

我们需要安装 BeautifulSoup 使用的lxml模块。

$ sudo pip3 install bs4

上面的命令将安装 BeautifulSoup。

HTML 文件

在示例中,我们将使用以下 HTML 文件:

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Header</title>
        <meta charset="utf-8">                   
    </head>

    <body>
        <h2>Operating systems</h2>

        <ul id="mylist" style="width:150px">
            <li>Solaris</li>
            <li>FreeBSD</li>
            <li>Debian</li>                      
            <li>NetBSD</li>           
            <li>Windows</li>         
        </ul>

        <p>
          FreeBSD is an advanced computer operating system used to 
          power modern servers, desktops, and embedded platforms.
        </p>

        <p>
          Debian is a Unix-like computer operating system that is 
          composed entirely of free software.
        </p>        

    </body>    
</html>

BeautifulSoup 简单示例

在第一个示例中,我们使用 BeautifulSoup 模块获取三个标签。

simple.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.h2)
    print(soup.head)
    print(soup.li)

该代码示例将打印三个标签的 HTML 代码。

from bs4 import BeautifulSoup

我们从bs4模块导入BeautifulSoup类。 BeautifulSoup是从事工作的主要类。

with open("index.html", "r") as f:

    contents = f.read()

我们打开index.html文件并使用read()方法读取其内容。

soup = BeautifulSoup(contents, 'lxml')

创建了BeautifulSoup对象; HTML 数据将传递给构造器。 第二个选项指定解析器。

print(soup.h2)
print(soup.head)

在这里,我们打印两个标签的 HTML 代码:h2head

print(soup.li)

有多个li元素; 该行打印第一个。

$ ./simple.py 
<h2>Operating systems</h2>
<head>
<title>Header</title>
<meta charset="utf-8"/>
</head>
<li>Solaris</li>

这是输出。

BeautifulSoup 标签,名称,文本

标记的name属性给出其名称,text属性给出其文本内容。

tags_names.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print("HTML: {0}, name: {1}, text: {2}".format(soup.h2, 
        soup.h2.name, soup.h2.text))

该代码示例打印h2标签的 HTML 代码,名称和文本。

$ ./tags_names.py 
HTML: <h2>Operating systems</h2>, name: h2, text: Operating systems

这是输出。

BeautifulSoup 遍历标签

使用recursiveChildGenerator()方法,我们遍历 HTML 文档。

traverse_tree.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    for child in soup.recursiveChildGenerator():

        if child.name:

            print(child.name)

该示例遍历文档树并打印所有 HTML 标记的名称。

$ ./traverse_tree.py 
html
head
title
meta
body
h2
ul
li
li
li
li
li
p
p

在 HTML 文档中,我们有这些标签。

BeautifulSoup 子元素

使用children属性,我们可以获取标签的子级。

get_children.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    root = soup.html

    root_childs = [e.name for e in root.children if e.name is not None]
    print(root_childs)

该示例检索html标记的子代,将它们放置在 Python 列表中,然后将其打印到控制台。 由于children属性还返回标签之间的空格,因此我们添加了一个条件,使其仅包含标签名称。

$ ./get_children.py 
['head', 'body']

html标签有两个子元素:headbody

BeautifulSoup 后继元素

使用descendants属性,我们可以获得标签的所有后代(所有级别的子级)。

get_descendants.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    root = soup.body

    root_childs = [e.name for e in root.descendants if e.name is not None]
    print(root_childs)

该示例检索body标记的所有后代。

$ ./get_descendants.py 
['h2', 'ul', 'li', 'li', 'li', 'li', 'li', 'p', 'p']

这些都是body标签的后代。

BeautifulSoup 网页抓取

请求是一个简单的 Python HTTP 库。 它提供了通过 HTTP 访问 Web 资源的方法。

scraping.py

#!/usr/bin/python3

from bs4 import BeautifulSoup
import requests as req

resp = req.get("http://www.something.com")

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.title)
print(soup.title.text)
print(soup.title.parent)

该示例检索一个简单网页的标题。 它还打印其父级。

resp = req.get("http://www.something.com")

soup = BeautifulSoup(resp.text, 'lxml')

我们获取页面的 HTML 数据。

print(soup.title)
print(soup.title.text)
print(soup.title.parent)

我们检索标题的 HTML 代码,其文本以及其父级的 HTML 代码。

$ ./scraping.py 
<title>Something.</title>
Something.
<head><title>Something.</title></head>

这是输出。

BeautifulSoup 美化代码

使用prettify()方法,我们可以使 HTML 代码看起来更好。

prettify.py

#!/usr/bin/python3

from bs4 import BeautifulSoup
import requests as req

resp = req.get("http://www.something.com")

soup = BeautifulSoup(resp.text, 'lxml')

print(soup.prettify()) 

我们美化了一个简单网页的 HTML 代码。

$ ./prettify.py 
<html>
 <head>
  <title>
   Something.
  </title>
 </head>
 <body>
  Something.
 </body>
</html>

这是输出。

BeautifulSoup 通过 ID 查找元素

使用find()方法,我们可以通过各种方式(包括元素 ID)查找元素。

find_by_id.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    #print(soup.find("ul", attrs={ "id" : "mylist"}))
    print(soup.find("ul", id="mylist")) 

该代码示例查找具有mylist ID 的ul标签。 带注释的行是执行相同任务的另一种方法。

BeautifulSoup 查找所有标签

使用find_all()方法,我们可以找到满足某些条件的所有元素。

find_all.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    for tag in soup.find_all("li"):
        print("{0}: {1}".format(tag.name, tag.text))

该代码示例查找并打印所有li标签。

$ ./find_all.py 
li: Solaris
li: FreeBSD
li: Debian
li: NetBSD

这是输出。

find_all()方法可以获取要搜索的元素列表。

find_all2.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tags = soup.find_all(['h2', 'p'])

    for tag in tags:
        print(" ".join(tag.text.split())) 

该示例查找所有h2p元素并打印其文本。

find_all()方法还可以使用一个函数,该函数确定应返回哪些元素。

find_by_fun.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

def myfun(tag):

    return tag.is_empty_element

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tags = soup.find_all(myfun)
    print(tags) 

该示例打印空元素。

$ ./find_by_fun.py 
[<meta charset="utf-8"/>]

文档中唯一的空元素是meta

也可以使用正则表达式查找元素。

regex.py

#!/usr/bin/python3

import re

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    strings = soup.find_all(string=re.compile('BSD'))

    for txt in strings:

        print(" ".join(txt.split())) 

该示例打印包含"BSD"字符串的元素的内容。

$ ./regex.py 
FreeBSD
NetBSD
FreeBSD is an advanced computer operating system used to power modern servers, desktops, and embedded platforms.

这是输出。

BeautifulSoup CSS 选择器

通过select()select_one()方法,我们可以使用一些 CSS 选择器来查找元素。

select_nth_tag.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.select("li:nth-of-type(3)"))

本示例使用 CSS 选择器来打印第三个li元素的 HTML 代码。

$ ./select_nth_tag.py 
<li>Debian</li>

这是第三个li元素。

CSS 中使用#字符通过 ID 属性选择标签。

select_by_id.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    print(soup.select_one("#mylist")) 

该示例打印具有mylist ID 的元素。

BeautifulSoup 附加元素

append()方法将新标签附加到 HTML 文档。

append_tag.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    newtag = soup.new_tag('li')
    newtag.string='OpenBSD'

    ultag = soup.ul

    ultag.append(newtag)

    print(ultag.prettify()) 

该示例附加了一个新的li标签。

newtag = soup.new_tag('li')
newtag.string='OpenBSD'

首先,我们使用new_tag()方法创建一个新标签。

ultag = soup.ul

我们获得对ul标签的引用。

ultag.append(newtag)

我们将新创建的标签附加到ul标签。

print(ultag.prettify()) 

我们以整齐的格式打印ul标签。

BeautifulSoup 插入元素

insert()方法在指定位置插入标签。

insert_tag.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    newtag = soup.new_tag('li')
    newtag.string='OpenBSD'

    ultag = soup.ul

    ultag.insert(2, newtag)

    print(ultag.prettify()) 

该示例将第三个位置的li标签插入ul标签。

BeautifulSoup 替换文字

replace_with()替换元素的文本。

replace_text.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    tag = soup.find(text="Windows")
    tag.replace_with("OpenBSD")

    print(soup.ul.prettify()) 

该示例使用find()方法查找特定元素,并使用replace_with()方法替换其内容。

BeautifulSoup 删除元素

decompose()方法从树中删除标签并销毁它。

decompose_tag.py

#!/usr/bin/python3

from bs4 import BeautifulSoup

with open("index.html", "r") as f:

    contents = f.read()

    soup = BeautifulSoup(contents, 'lxml')

    ptag2 = soup.select_one("p:nth-of-type(2)")

    ptag2.decompose()

    print(soup.body.prettify())

该示例删除了第二个p元素。

在本教程中,我们使用了 Python BeautifulSoup 库。

您可能也会对以下相关教程感兴趣: Pyquery 教程Python 教程Python 列表推导OpenPyXL 教程,Python Requests 教程和 Python CSV 教程

PyQuery 教程

原文: http://zetcode.com/python/pyquery/

PyQuery 教程展示了如何在 Python 中对 XML 文档进行 jQuery 查询。

jQuery

jQuery 是一个 JavaScript 库,用于处理 DOM。 使用 jQuery,我们可以查找,选择,遍历和操作 HTML 文档的各个部分。

PyQuery

PyQuery 是一个 Python 库,具有与 jQuery 类似的 API。 它使用lxml模块进行快速的 XML 和 HTML 操作。 该 API 尽可能类似于 jQuery。

安装 PyQuery

使用以下命令安装 PyQuery:

$ sudo pip3 install pyquery

我们使用pip3命令安装 PyQuery 模块。

HTML 文件

在示例中,我们将使用以下 HTML 文件:

index.html

<!DOCTYPE html>
<html>
    <head>
        <title>Header</title>
        <meta charset="utf-8">                   
    </head>

    <body>
        <h2>Operating systems</h2>

        <ul id="mylist" style="width:150px">
            <li>Solaris</li>
            <li>FreeBSD</li>
            <li>Debian</li>                      
            <li>NetBSD</li>           
            <li>Windows</li>         
        </ul>
    </body>    
</html>

简单的例子

在第一个示例中,我们使用 PyQuery 模块获取标头的文本。

header.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)
    text = doc("h2").text()

    print(text)

该代码示例打印h2元素的文本。

from pyquery import PyQuery as pq

我们从pyquery模块导入PyQuery类。 PyQuery是从事工作的主要类。

with open("index.html", "r") as f:

    contents = f.read()

我们打开index.html文件并使用read()方法读取其内容。

doc = pq(contents)

创建了PyQuery对象; HTML 数据将传递给构造器。

text = doc("h2").text()

我们选择h2标签,并使用text()方法获取其文本。

$ ./header.py 
Operating systems

这是输出。

文本和 HTML 方法

text()方法检索元素的文本,而html()方法检索元素的 HTML 数据。

get_list.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)

    text = doc("ul").text()
    print("\n".join(text.split()))

    text = doc("ul").html()
    print("\n".join(text.split()))    

我们获得ul元素的文本数据和 HTML 数据。

$ ./get_list.py 
Solaris
FreeBSD
Debian
NetBSD
Windows
<li>Solaris</li>
<li>FreeBSD</li>
<li>Debian</li>
<li>NetBSD</li>
<li>Windows</li>

这是输出。

属性

元素属性可以使用attr()方法检索。

attributes.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)

    tag = doc("ul")

    print(tag.attr("id"))
    print(tag.attr("style")) 

在代码示例中,我们检索并打印ul元素的两个属性:idstyle

$ ./attributes.py 
mylist
width:150px

这是输出。

网页抓取

请求是一个简单的 Python HTTP 库。 它提供了通过 HTTP 访问 Web 资源的方法。

scraping.py

#!/usr/bin/python3

from pyquery import PyQuery as pq
import requests as req

resp = req.get("http://www.something.com")
doc = pq(resp.text)

title = doc('title').text()
print(title)

该示例检索一个简单网页的标题。

resp = req.get("http://www.something.com")
doc = pq(resp.text)

我们获取页面的 HTML 数据。

title = doc('title').text()
print(title)

我们检索其标题。

$ ./scraping.py 
Something.

这是输出。

选择标签

选择器用于选择 HTML 文档中满足某些条件的元素。 条件可以是它们的名称,ID,类名称,属性或它们的组合。

selecting.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

def print_item(self, item):

    print("Tag: {0}, Text: {1}".format(item.tag, item.text))

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)

    first_li = doc("li:first")
    print(first_li.text())

    last_li = doc("li:last")
    print(last_li.text())

    odd_lis = doc("li:odd")    
    odd_lis.each(print_item)

该示例从 HTML 文档中选择各种li标签。

def print_item(self, item):

    print("Tag: {0}, Text: {1}".format(item.tag, item.text))

在此函数中,我们打印标签名称及其文本。

first_li = doc("li:first")
print(first_li.text())

我们选择第一个li标签,并使用text()方法打印其内容。

last_li = doc("li:last")
print(last_li.text())

在这里,我们得到了最后的li标签。

odd_lis = doc("li:odd")    
odd_lis.each(print_item)

借助each()方法,我们将打印每个奇数li元素的标签及其内容。

$ ./selecting.py 
Solaris
Windows
Tag: li, Text: FreeBSD
Tag: li, Text: NetBSD

这是输出。

移除元素

remove()方法删除标签。

removing.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)

    removed_item = doc('li:last').remove()

    print(removed_item)
    print(doc)

在示例中,我们删除了最后一个li标签。

removed_item = doc('li:last').remove()

我们选择最后一个li标签,然后用remove()删除它。 返回删除的元素。

print(removed_item)
print(doc)

我们将打印已删除的项目和已删除元素的文档。

$ ./removing.py 
<li>Windows</li>         

<html>
    <head>
        <title>Header</title>
        <meta charset="utf-8"/>                   
    </head>

    <body>
        <h2>Operating systems</h2>

        <ul id="mylist" style="width:150px">
            <li>Solaris</li>
            <li>FreeBSD</li>
            <li>Debian</li>                      
            <li>NetBSD</li>           

        </ul>
    </body>    
</html>

这是输出。

items方法

items()方法允许迭代元素。

iterate.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)

    items = [item.text() for item in doc.items('li')]
    print(items)

该示例迭代文档的li元素。

items = [item.text() for item in doc.items('li')]

items()方法用于在列表推导式中创建li元素的 Python 列表。

$ ./iterate.py 
['Solaris', 'FreeBSD', 'Debian', 'NetBSD', 'Windows']

这是输出。

附加和前置元素

append()方法在节点的末尾添加元素,prepend()方法在节点的末尾添加元素。

append_prepend.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)
    mylist = doc("#mylist")

    mylist.prepend("<li>DragonFly</li>")
    mylist.append("<li>OpenBSD</li>")

    print(mylist)

该代码示例使用prepend()append()方法插入两个li元素。

filter方法

filter()方法用于过滤元素。

filtering.py

#!/usr/bin/python3

from pyquery import PyQuery as pq

with open("index.html", "r") as f:

    contents = f.read()

    doc = pq(contents)

    filtered = doc('li').filter(lambda i: pq(this).text().startswith(('F', 'D', 'N')))
    print(filtered.text())

该示例显示了以FDN开头的操作系统。我们使用filter()方法和匿名函数。

 ./filtering.py 
FreeBSD Debian NetBSD

这是输出。

在本教程中,我们使用了 python PyQuery 库。

您可能也对以下相关教程感兴趣: jQuery 教程Beautifulsoup 教程Python 教程Python FTP 教程,Python 列表推导, OpenPyXL 教程Python Requests 教程Python CSV 教程

Python for循环

原文: http://zetcode.com/python/forloop/

Python for循环教程展示了如何使用for语句在 Python 中创建循环。

Python 循环定义

循环是连续重复的指令序列,直到达到特定条件为止。 例如,我们有一个项目集合,我们创建了一个循环以遍历该集合的所有元素。 可以使用forwhile语句创建 Python 中的循环。

Python 语句

Python for语句按照它们在序列中出现的顺序遍历任何序列的项(例如列表或字符串)。

for var in sequence:
   do_statement(s)

上面是 Python for语句的一般语法。

Python 的字符串循环

以下示例使用 Python for语句遍历字符串。

for_loop_string.py

#!/usr/bin/python3

word = "cloud"

for let in word:

    print(let)

我们定义了一个字符串。 通过for循环,我们将单词的字母一一打印到终端。

$ ./for_loop_string.py 
c
l
o
u
d

这是示例的输出。

Python for循环的else

for循环具有可选的else语句,该语句在循环完成时执行。

for_loop_else.py

#!/usr/bin/python3

words = ["cup", "star", "monkey", "bottle", "paper", "door"]

for word in words:

    print(word)
else:

    print("Finished looping")    

我们使用for循环遍历单词列表。 迭代结束后,我们将打印"Finished looping"消息,该消息位于else关键字之后的主体中。

$ ./for_loop_else.py 
cup
star
monkey
bottle
paper
door
Finished looping

这是示例的输出。

Python 的范围循环

Python range()函数生成一个数字列表。

range(n)

该函数生成数字0 ... n-1

range(start, stop, [step])

该函数生成一个数字序列; 它以start开头,以stop结束,该序列中未包含该字符。 step是增量,如果未提供,则默认为 1。

借助range()函数,我们可以将代码块重复 n 次。

repeating_statement.py

#!/usr/bin/python3

for i in range(1, 6):

    print("Statement executed {0}".format(i))

该代码示例执行该代码块五次。

$ ./repeating_statement.py 
Statement executed 1
Statement executed 2
Statement executed 3
Statement executed 4
Statement executed 5

这是输出。

在下一个示例中,我们使用for循环生成两个整数序列。

for_loop_range.py

#!/usr/bin/python3

for n in range(1, 11):

    print(n, end=' ')

print()    

for n in range(0, 11, 2):

    print(n, end=' ')    

print()  

该示例打印两个整数序列:1,2,... 10 和 0,2,... 10。

$ ./for_loop_range.py 
1 2 3 4 5 6 7 8 9 10 
0 2 4 6 8 10 

这是输出。

Python 遍历元组和列表

使用 Python for循环,我们可以轻松地遍历 Python 元组和列表。

for_loop_tuple_list.py

#!/usr/bin/python3

nums = (1, 2, 3, 4, 5, 6)   
words = ["cup", "star", "monkey", "bottle"]

for n in nums:

    print(n, end=' ')

print()

for word in words:

    print(word, end=' ')

print()    

该代码示例输出一个元组和一个列表的元素。

$ ./for_loop_tuple_list.py 
1 2 3 4 5 6 
cup star monkey bottle 

这是输出。

Python 索引循环

有时我们也需要获取元素的索引。 为此,我们可以使用enumerate()函数。

for_loop_index.py

#!/usr/bin/python3

words = ("cup", "star", "monkey", "bottle", "paper", "door")

for idx, word in enumerate(words):

    print("{0}: {1}".format(idx, word))

借助enumerate()函数,我们将打印列表元素及其索引。

$ ./for_loop_index.py 
0: cup
1: star
2: monkey
3: bottle
4: paper
5: door

Python 遍历字典

在以下示例中,我们遍历了 Python 字典。

for_loop_dictionary.py

#!/usr/bin/python3

data = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary", "ru": "Russia" }    

for k, v in data.items():

    print("{0} is an abbreviation for {1}".format(k, v))

该代码示例将打印 Python 字典的键和值。

$ ./for_loop_dictionary.py 
sk is an abbreviation for Slovakia
ru is an abbreviation for Russia
hu is an abbreviation for Hungary
de is an abbreviation for Germany

这是输出。

Python 嵌套循环

可以将for循环嵌套到另一个循环中。

for_loop_nested.py

#!/usr/bin/python3

nums = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

for i in nums:

    for e in i:

        print(e, end=' ')

    print()

我们有一个二维整数列表。 我们通过两个for循环遍历元素。

$ ./for_loop_nested.py 
1 2 3 
4 5 6 
7 8 9 

这是输出。

Python for循环的zip

zip()函数根据给定的可迭代对象创建一个迭代器。

for_loop_zip.py

#!/usr/bin/python3

words1 = ["cup", "bottle", "table", "rock", "apple"]
words2 = ["trousers", "nail", "head", "water", "pen"]

for w1, w2 in zip(words1, words2):

    print(w1, w2)

在示例中,我们在一个for循环中迭代两个列表。

$ ./for_loop_zip.py 
cup trousers
bottle nail
table head
rock water
apple pen

这是输出。

Python 循环自定义可迭代对象

在下一个示例中,我们遍历了一个自定义迭代器。

for_loop_custom_iterable.py

#!/usr/bin/python3

import random

def myrandom(x):

    i = 0

    while i < x:

        r = random.randint(0, 100)

        yield r

        i = i + 1

for r in myrandom(5):

    print(r)

该代码示例创建一个生成器函数,该函数生成随机整数。 通过for循环,我们生成五个随机整数。

$ ./for_loop_custom_iterable.py 
14
43
53
44
70

这是一个示例输出。

Python for循环break

break语句终止for循环。

for_loop_break.py

#!/usr/bin/python3

import random
import itertools 

for i in itertools.count():

   val = random.randint(1, 30)
   print(val)

   if (val == 22):
      break

在示例中,我们创建了一个无限的for循环。 我们从1 ... 29生成并打印随机数。 如果生成的数字等于 22,则for循环以break关键字结束。

$ ./for_loop_break.py 
7
27
2
27
7
9
3
25
15
22

这是一个示例输出。

Python 循环continue

continue关键字用于中断当前循环,而不会跳出整个循环。 它启动一个新的循环。

for_loop_continue.py

#!/usr/bin/python3

num = 0

for num in range(1000):

   num = num + 1

   if (num % 2) == 0:
      continue

   print(num, end=' ')

print() 

我们打印所有小于 1000 的数字,这些数字不能除以 2 而没有余数。

在本教程中,我们使用 Python 进行循环。

您可能也对以下相关教程感兴趣: Python 教程Python 集教程Python lambda 函数Python 列表推导Python 映射教程Python 反向教程OpenPyXL 教程Python Requests 教程Python CSV 教程

Python 反转

原文: http://zetcode.com/python/reverse/

在本教程中,我们展示了如何反转 Python 序列。

当我们撤消项目时,我们会更改其顺序。 请注意,不应将反转与降序排序混淆。

Python 列表具有reverse()函数。 [::-1] 切片操作可反转 Python 序列。 reversed()内置函数返回反转迭代器。 内置reversed()调用对象的__reversed__()魔术方法以实现反转迭代。

Python 反转列表

在第一个示例中,我们使用reverse()方法和[::-1]运算符反转 Python 列表。

reverse_list.py

#!/usr/bin/env python3

nums = [2, 7, 8, 9, 1, 0]
nums.reverse()

print(nums)

rev_nums = nums[::-1]
print(rev_nums)

reverse()方法在适当的位置反转列表。 nums[::-1]创建一个列表的新副本,其中元素被反转。

$ ./reverse_list.py
[0, 1, 9, 8, 7, 2]

这是输出。

Python reversed函数

reversed()内置函数返回反转迭代器。

reversed_fun.py

#!/usr/bin/env python3

words = ['forest', 'wood', 'sky', 'rock']

for word in reversed(words):
    print(word)

word = 'forest'

for e in reversed(word):
    print(e, end=' ')

print()

for e in reversed(range(1, 10, 2)):
    print(e)

在示例中,我们在列表,单词和范围上使用reversed()函数。

$ ./reversed_fun.py
rock
sky
wood
forest
t s e r o f
9
7
5
3
1

这是输出。

Python 自定义反转字符串函数

在下面的示例中,我们创建一个自定义字符串反转函数。

custom_string_reverse.py

#!/usr/bin/env python3

def reverse_string(word):

    rev = ''
    n = len(word)

    while n > 0:
        n -= 1                 
        rev += word[n] 
    return rev

word = 'forest'

print(reverse_string('forest'))

请注意,这只是出于演示目的; 这个实现很慢。

def reverse_string(word):

    rev = ''
    n = len(word)

    while n > 0:
        n -= 1                 
        rev += word[n] 
    return rev

在函数中,我们使用while循环以相反的顺序构建新字符串。

Python __reversed__方法

__reversed__()魔术方法实现应返回一个新的迭代器对象,该对象以相反的顺序遍历容器中的所有对象。

reversed_magic.py

#!/usr/bin/env python3

class Vowels(object):

    def __init__(self):

        self.vowels = ['a', 'e', 'i', 'o', 'u', 'y']

    def __len__(self):
        return len(self.vowels)

    def __getitem__(self, e):
        return self.vowels[e]

    def __reversed__(self):
        for e in self.vowels[::-1]:
            yield elem        

vowels = Vowels()

print('normal order:')
for vowel in vowels:
    print(vowel, end=' ')

print()

print('reversed order:')
for vowel in reversed(vowels):
    print(vowel, end=' ')    

print()   

在示例中,我们在Vowels对象中实现__reversed__()方法。

$ ./reversed_magic.py
normal order:
a e i o u y
reversed order:
y u o i e a

这是输出。

在本教程中,我们已经在 Python 中完成了反转操作。

您可能也对以下相关教程感兴趣: Python 教程Python 集教程Python for循环Python 列表推导, 和 Python 映射教程

Python Lambda 函数

原文: http://zetcode.com/python/lambda/

Python lambda 函数教程展示了如何在 Python 中创建匿名函数。 Python 中的匿名函数是使用lambda关键字创建的。

Python Lambda 函数

Python lambda 函数(也称为匿名函数)是没有名称的内联函数。 它们是使用lambda关键字创建的。 这是内置 Python 的函数示例的一部分。

Python lambda 函数仅限于单个表达式。 它们可以在可以使用常规函数的任何地方使用。

Python Lambda 语法

Python lambda 具有以下语法:

z = lambda x: x * y

该语句使用lambda关键字创建一个匿名函数。 该函数将两个值相乘。 x是传递给 lambda 函数的参数。 参数后跟一个冒号。 冒号旁边的代码是调用 lambda 函数时执行的表达式。 lambda 函数分配给z变量。

Python Lambda 示例

以下是演示 Python lambda 函数的简单示例。

lambda_fun_simple.py

#!/usr/bin/python3

def square(x):

    return x * x

sqr_fun = lambda x: x * x

print(square(3))
print(sqr_fun(4))

在示例中,我们有两个函数对一个值求平方。

def square(x):

    return x * x

这是用def关键字定义的 Python 函数。 该函数的名称为square

sqr_fun = lambda x: x * x

在这里,我们使用lambda定义了一个匿名的内联函数。 请注意,该函数没有名称。 sqr_fun是保存已创建的 lambda 函数的变量的名称。

 ./lambda_fun_simple.py 
9
16

这是示例的输出。

Python Lambda 和map

Python lambda 函数可用于map()函数。 我们可以创建更简洁的代码。 Python map()是一个内置函数,该函数将给定函数应用于iterable的每一项,并返回一个迭代器对象。

lambda_fun_map.py

#!/usr/bin/python3

nums = [1, 2, 3, 4, 5, 6]

nums_squared = map(lambda x: x * x, nums)

for num in nums_squared:
    print(num)

该示例为map()创建一个 litle 内联函数作为参数。 使用map()函数,我们将 lambda 函数应用于列表的每个元素。

$ ./lambda_fun_map.py 
1
4
9
16
25
36

这是输出。

Python lambda 和filter

Python lambda 函数可以与filter()函数一起使用。 filter()函数根据可迭代的那些元素构造一个列表,这些元素为其返回true

lambda_fun_filter.py

#!/usr/bin/python3

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

nums_filtered = list(filter(lambda x: x % 2, nums))

print(nums_filtered)

在示例中,我们过滤了整数列表。 新列表仅包含奇数整数。

nums_filtered = list(filter(lambda x: x % 2, nums))

filter()的第一个参数是处理列表元素的函数。 lambda 函数具有x % 2表达式,对于奇数值返回true

$ ./lambda_fun_filter.py 
[1, 3, 5, 7, 9, 11]

这是输出。

Python Lambda 和 Tkinter

Python lambda 函数可用于 Tkinter 的 GUI 编程中。 它允许为command参数创建小的内联函数。

lambda_tkinter.py
#!/usr/bin/python3
# -*- coding: utf-8 -*-

from tkinter import Tk, BOTH, messagebox
from tkinter.ttk import Frame, Button

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)   

        self.parent = parent

        self.initUI()

    def initUI(self):

        self.parent.title("Buttons")

        self.pack(fill=BOTH, expand=1)

        btn1 = Button(self, text="Button 1",
            command=lambda: self.onClick("Button 1"))
        btn1.pack(padx=5, pady=5)

        btn2 = Button(self, text="Button 2",
            command=lambda: self.onClick("Button 2"))
        btn2.pack(padx=5, pady=5)

        btn2 = Button(self, text="Button 3",
            command=lambda: self.onClick("Button 3"))
        btn2.pack(padx=5, pady=5)   

    def onClick(self, text):

        messagebox.showinfo("Button label", text);

def main():

    root = Tk()
    root.geometry("250x150+300+300")
    app = Example(root)
    root.mainloop()  

if __name__ == '__main__':
    main()  

我们有三个按钮共享一个回调。 lambda 函数允许我们将特定数据发送到回调函数。 每个按钮在消息框中显示其标签。

btn1 = Button(self, text="Button 1",
    command=lambda: self.onClick("Button 1"))

我们将匿名函数传递给command参数。 我们将按钮的标签发送到onClick()回调。

在本教程中,我们使用了 Python lambda 函数。

您可能也对以下相关教程感兴趣: Python 教程Python 集教程Python for循环Python 列表推导Python 映射教程OpenPyXL 教程Python Requests 教程Python CSV 教程

Python 语法结构

原文: http://zetcode.com/lang/python/lexicalstructure/

像人类语言一样,计算机语言也具有语法结构。 Python 程序的源代码由令牌组成。 令牌是原子代码元素。 在 Python 语言中,我们具有注释,变量,字面值,运算符,定界符和关键字。

Python 注释

注释被人类用来阐明源代码。 Python 语言中的所有注释均以# 字符为准。

comments.py

#!/usr/bin/env python

# comments.py
# Author Jan Bodnar
# ZetCode 2017

def main():
    print("Comments example")

main()

Python 解释器将忽略# 字符后的所有内容。

Python 变量

变量是保存值的标识符。 在编程中,我们说我们为变量分配了一个值。 从技术上讲,变量是对存储值的计算机内存的引用。 在 Python 语言中,变量可以包含字符串,数字或各种对象,例如函数或类。 可以随时间为变量分配不同的值。

Python 中的变量可以由字母数字字符和下划线_字符创建。 变量不能以数字开头。 这样,Python 解释器可以更轻松地区分数字和变量。

Value
value2
company_name

这些是有效的标识符。

12Val
exx$
first-name

这些是无效标识符的示例。

变量为区分大小写。 这意味着PricepricePRICE是三个不同的标识符。

case.py

#!/usr/bin/env python

number = 10
Number = 11
NUMBER = 12

print(number, Number, NUMBER)

在脚本中,我们将三个数值分配给三个标识符。 虽然可以定义大小写不同的三个变量,但是这并不是一个好的编程习惯。

$ ./case.py
10 11 12

这是脚本的输出。

Python 字面值

字面值是表示 Python 源代码中的值的任何符号。 从技术上讲,字面值是在编译时分配一个值的,而变量是在运行时分配的。

age = 29
nationality = "Hungarian"

在这里,我们为变量分配了两个字面值。 数字29和字符串"Hungarian"是字面值。

literals.py

#!/usr/bin/env python

# literals.py

name1 = "Jane"
age1 = 12

name2 = "Rose"
age2 = 16

"Patrick"
34

"Luke"
23

print(name1, age1)
print(name2, age2)

如果我们不给变量分配字面值,就无法使用它。 它被丢弃。

$ ./literals.py
Jane 12
Rose 16

这是literals.py脚本的输出。

Python 运算符

运算符是用于对某个值执行操作的符号。

+    -    ~    *    **    /    //
%    <<    >>    &    |    ^
and    or    not    in    not in
is    is not    <   >    !=
==    <=    >=

这是 Python 语言中可用的运算符的列表。 我们将在本教程的后面部分讨论运算符。

Python 缩进

缩进用于在 Python 中定界。 在其他编程语言使用大括号或诸如beginend之类的关键字的情况下,Python 使用空格。 某些语句后缩进增加; 缩进的减少表示当前块的结尾。 Python 样式指南建议每个缩进级别使用四个空格。

if age > 18:
    print("adult person")

for i in range(5):
    print(i)

if关键字之后,需要一个代码块。 新的语句在新行上开始,并以四个空格字符缩进。 随后的for关键字的缩进减少到最初的关键字。 for关键字启动一个新的代码块,在该代码块中缩进其语句。

Python 分隔符

定界符是一个或多个字符的序列,用于指定纯文本或其他数据流中单独的独立区域之间的边界。

(       )       [       ]       {       }
,       :       .       `       =       ;
+=      -=      *=      /=      //=     %=
<=      |=      ^=      >>=     <<=     **=
'       "       \       @

分隔符用于 Python 语言的各个领域。 它们用于构建表达式,字符串字面值,元组,字典或列表。

Python 关键字

关键字是 Python 编程语言中的保留字。 关键字用于在计算机程序中执行特定任务。 例如,导入其他代码,执行重复性任务或执行逻辑操作。 程序员不能将关键字用作普通变量。

and       del       global      not      with
as        elif      if          or       yield
assert    else      import      pass     False
break     except    in          raise    None
class     finally   is          return   True
continue  for       lambda      try
def       from      nonlocal    while

这是 Python 关键字的列表。 在本教程中,我们专门为关键字专门章节。

这就是 Python 的语法结构。

Python 集

原文: http://zetcode.com/python/set/

Python set教程介绍了 Python set集合。 我们展示了如何创建集并对其执行操作。

Python 集

Python 集是无序数据集,没有重复的元素。 集支持数学中已知的诸如并集,相交或求差的运算。

Python 集字面值

从 Python 2.6 开始,可以使用字面值符号创建集。 我们使用大括号在 Python 中定义一个集,并且元素之间用逗号分隔。

python_set_literal.py

#!/usr/bin/python3

nums = { 1, 2, 2, 2, 3, 4 }

print(type(nums))
print(nums)

该示例创建带有字面值符号的 Python 集。

nums = { 1, 2, 2, 2, 3, 4 }

集是唯一元素的集; 即使我们提供了 3 次值 2,该集也只包含一个 2。

$ ./python_set_literal.py 
<class 'set'>
{1, 2, 3, 4}

这是输出。

Python 集函数

Python set()函数创建一个新集,其元素来自可迭代对象。 可迭代对象是我们可以迭代的对象; 例如字符串或列表。

python_set_fun.py

#!/usr/bin/python3

seasons = ["spring", "summer", "autumn", "winter"]

myset = set(seasons)

print(myset)

在示例中,我们使用set()内置函数从列表创建了一个集。

$ ./python_set_fun.py 
{'summer', 'autumn', 'winter', 'spring'}

这是输出。

Python 集成员性测试

innot in运算符测试集中元素的存在。

python_set_membership.py

#!/usr/bin/python3

words = { "spring", "table", "cup", "bottle", "coin" }

word = 'cup'

if (word in words):
    print("{0} is present in the set".format(word))
else:
    print("{0} is not present in the set".format(word))    

word = 'tree'

if (word not in words):
    print("{0} is not present in the set".format(word))
else:
    print("{0} is present in the set".format(word)) 

我们使用成员运算符检查集中是否存在两个单词。

$ ./python_set_membership.py 
cup is present in the set
tree is not present in the set

这是输出。

Python 集内置函数

有几个内置 Python 函数,例如len()min(),可以在 Python 集上使用。

python_set_builtins.py

#!/usr/bin/python3

nums = { 21, 11, 42, 29, 22, 71, 18 }

print(nums)

print("Number of elements: {0}".format(len(nums)))
print("Minimum: {0}".format(min(nums)))
print("Maximum: {0}".format(max(nums)))
print("Sum: {0}".format(sum(nums)))

print("Sorted elements:")

print(sorted(nums))

在示例中,我们对一组整数值应用了五个内置函数。

print("Number of elements: {0}".format(len(nums)))

len()方法返回集中的元素数。

print("Minimum: {0}".format(min(nums)))

min()方法返回集中的最小值。

print("Maximum: {0}".format(max(nums)))

max()方法返回集中的最大值。

print("Sum: {0}".format(sum(nums)))

sum()方法返回集中值的总和。

print(sorted(nums))

最后,使用sorted()方法,我们可以从集中创建无序列表。

$ ./python_set_builtins.py 
{71, 42, 11, 18, 21, 22, 29}
Number of elements: 7
Minimum: 11
Maximum: 71
Sum: 214
Sorted elements:
[11, 18, 21, 22, 29, 42, 71]

这是输出。

Python 集迭代

可以使用for循环来迭代 Python 集。

python_set_iteration.py

#!/usr/bin/python3

words = { "spring", "table", "cup", "bottle", "coin" }

for word in words:

    print(word)

在示例中,我们遍历该集并逐个打印其元素。

$ ./python_set_iteration.py 
table
cup
coin
spring
bottle

这是输出。

Python 集添加

Python set add()方法将新元素添加到集中。

python_set_add.py

#!/usr/bin/python3

words = { "spring", "table", "cup", "bottle", "coin" }

words.add("coffee")

print(words)

我们有一套话。 我们使用add()方法添加一个新单词。

$ ./python_set_add.py 
{'table', 'coffee', 'coin', 'spring', 'bottle', 'cup'}

这是输出。

Python 集更新

Python set update()方法将一个或多个可迭代对象添加到集中。

python_set_update.py

#!/usr/bin/python3

words = { "spring", "table", "cup", "bottle", "coin" }

words.add("coffee")

print(words)

words2 = { "car", "purse", "wind" }
words3 = { "nice", "prime", "puppy" }

words.update(words2, words3)

print(words)

我们有三组单词。 我们使用update()方法将第二组和第三组添加到第一组。

$ ./python_set_update.py 
{'spring', 'bottle', 'cup', 'coin', 'purse', 'wind', 'nice', 'car', 
 'table', 'prime', 'puppy'}

这是输出。

Python 集删除

Python 有两种删除元素的基本方法:remove()discard()remove()方法从集中删除指定的元素,如果元素不在集中,则提高KeyErrordiscard()方法从集中删除元素,如果要删除的元素不在集中,则不执行任何操作。

python_set_remove.py

#!/usr/bin/python3

words = { "spring", "table", "cup", "bottle", "coin" }

words.discard("coin")
words.discard("pen")

print(words)

words.remove("cup")

try:
    words.remove("cloud")
except KeyError as e:
    pass    

print(words)

在示例中,我们使用remove()discard()删除集元素。

try:
    words.remove("cloud")
except KeyError as e:
    pass  

如果我们没有抓住KeyError,脚本将终止而不执行最后一条语句。

$ ./python_set_remove.py 
{'table', 'cup', 'bottle', 'spring'}
{'table', 'bottle', 'spring'}

这是输出。

Python 集弹出&清除

pop()方法从集中移除并返回任意元素。 clear()方法从集中删除所有元素。

python_set_remove2.py

#!/usr/bin/python3

words = { "spring", "table", "cup", "bottle", "coin", "pen", "water" }

print(words.pop())
print(words.pop())

print(words)

words.clear()

print(words)

在示例中,我们删除并打印两个随机元素,并显示其余元素。 然后,使用clear()从集中删除所有元素。

$ ./python_set_remove2.py 
water
pen
{'cup', 'spring', 'table', 'bottle', 'coin'}
set()

这是输出。

Python 集运算

使用 Python 集,我们可以执行特定的运算:并集,交集,差和对称差。

python_set_operations.py

#!/usr/bin/python3

set1 = { 'a', 'b', 'c', 'c', 'd' }
set2 = { 'a', 'b', 'x', 'y', 'z' }

print("Set 1:", set1)
print("Set 2:", set2)
print("intersection:", set1.intersection(set2))
print("union:", set1.union(set2))
print("difference:", set1.difference(set2))
print("symmetric difference:", set1.symmetric_difference(set2))

该示例显示了四个设置操作。

print("intersection:", set1.intersection(set2))

intersection()方法执行相交操作,该操作返回set1set2中的元素。

print("union:", set1.union(set2))

union()方法执行联合操作,该操作返回两个集中的所有元素。

print("difference:", set1.difference(set2))

difference()方法执行差分操作,该操作返回set1中而不是set2中的元素。

print("symmetric difference:", set1.symmetric_difference(set2))

symmetric_difference()方法执行对称差分操作,该操作返回set1set2中的元素,但不返回两者中的元素。

$ ./python_set_operations.py 
Set 1: {'c', 'b', 'a', 'd'}
Set 2: {'y', 'b', 'a', 'x', 'z'}
intersection: {'b', 'a'}
union: {'b', 'a', 'z', 'c', 'x', 'y', 'd'}
difference: {'c', 'd'}
symmetric difference: {'z', 'c', 'x', 'y', 'd'}

这是一个示例输出。

可以使用&,|,-和^运算符执行这些操作。

python_set_operations2.py

#!/usr/bin/python3

set1 = { 'a', 'b', 'c', 'c', 'd' }
set2 = { 'a', 'b', 'x', 'y', 'z' }

print("Set 1:", set1)
print("Set 2:", set2)
print("intersection:", set1 & set2)
print("union:", set1 | set2)
print("difference:", set1 - set2)
print("symmetric difference:", set1 ^ set2)

该示例显示了使用运算符的四个set操作。

子集和超集

如果集 A 的所有元素都包含在集 B 中,则将 A 称为 B 的子集,将 B 称为 A 的超集。

python_subset_superset.py

#!/usr/bin/python3

set1 = { 'a', 'b', 'c', 'd', 'e' }
set2 = { 'a', 'b', 'c' }
set3 = {'x', 'y', 'z' }

if (set2.issubset(set1)):
    print("set2 is a subset of set1")

if (set1.issuperset(set2)):
    print("set1 is a superset of set2")    

if (set2.isdisjoint(set3)):
    print("set2 and set3 have no common elements")     

在示例中,我们使用issubset()issuperset()isdisjoint()方法。

if (set2.issubset(set1)):
    print("set1 is a subset of set2")

使用issubset()方法,我们检查set2是否是s1的子集。

if (set1.issuperset(set2)):
    print("set1 is a superset of set2")   

使用issuperset()方法,我们检查set1是否是s2的超集。

if (set2.isdisjoint(set3)):
    print("set2 and set3 have no common elements")      

使用isdisjoint()方法,我们检查set2set3是否没有共同的元素。

$ ./python_subset_superset.py 
set1 is a subset of set2
set1 is a superset of set2
set2 and set3 have no common elements

这是输出。

Python 不可变集

不可变的集(无法修改的集)是使用frozenset()函数创建的。

>>> s1 = frozenset(('blue', 'green', 'red'))
>>> s1
frozenset({'red', 'green', 'blue'})
>>> s1.add('brown')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add'

当我们尝试向冻结集中添加新元素时出现错误。

在本教程中,我们使用了 Python set集。

您可能也对以下相关教程感兴趣: Python 教程Python lambda 函数Python for循环Python 列表推导Python 映射教程OpenPyXL 教程Python Requests 教程Python CSV 教程

Python 映射

原文: http://zetcode.com/python/map/

Python 映射教程介绍了 Python 内置的map()函数。

Python map()函数

Python map()内置函数将给定函数应用于可迭代的每一项,并返回一个迭代器对象。

map(function, iterable, ...)

可以将多个迭代传递给map()函数。 该函数必须采用与可迭代项一样多的参数。

Python 映射示例

以下示例在整数列表上使用 Python map()

python_map.py

#!/usr/bin/python3

def square(x):

    return x * x

nums = [1, 2, 3, 4, 5]

nums_squared = map(square, nums)

for num in nums_squared:

    print(num)

我们定义一个整数列表,并使用map()在列表的每个元素上应用square()函数。

def square(x):

    return x * x

square()函数平方其参数。

nums = [1, 2, 3, 4, 5]

我们定义一个整数列表。

nums_squared = map(square, nums)

map()函数将square()函数应用于nums列表的每个元素。

for num in nums_squared:

    print(num)

我们遍历返回的iterable并打印元素。

$ ./python_map.py 
1
4
9
16
25

这是输出。

等效的 Python 映射

以下示例显示了与 Python 3 map()函数等效的自定义。

mymap_fun.py

#!/usr/bin/python3

def square(x):

    return x * x

def mymap(func, iterable):

    for i in iterable:
        yield func(i)

nums = [1, 2, 3, 4, 5]

nums_squared = mymap(square, nums)

for num in nums_squared:

    print(num)  

mymap()与 Python 3 map()做相同的事情。

带 lambda 的 Python 映射

下一个示例使用lambda运算符在map()内部创建一个匿名函数。

python_map_lambda.py

#!/usr/bin/python3

nums = [1, 2, 3, 4, 5]

nums_squared = map(lambda x: x*x, nums)

for num in nums_squared:
    print(num)

该代码示例将列表元素与map()平方在一起,并将匿名函数与lambda创建。

具有多个可迭代项的 Python 映射

前面已经提到过,我们可以将多个可迭代对象传递给map()

python_map_iterables.py

#!/usr/bin/python3

def multiply(x, y):

    return x * y

nums1 = [1, 2, 3, 4, 5]
nums2 = [6, 7, 8, 9, 10]

mult = map(multiply, nums1, nums2)

for num in mult:
    print(num)

在代码示例中,有两个持有整数的可迭代对象。 来自两个可迭代对象的值相乘。

def multiply(x, y):

    return x * y

该函数必须带有两个参数,因为有两个可迭代变量传递给map()

$ ./python_map_iterables.py 
6
14
24
36
50

这是输出。

Python 映射多个函数

在下一个示例中,我们显示如何在 Python map()中使用多个函数。

python_map_multiple_funcs.py

#!/usr/bin/python3

def add(x):
    return x + x

def square(x):
    return x * x

nums = [1, 2, 3, 4, 5]

for i in nums:

    vals = list(map(lambda x: x(i), (add, square)))

    print(vals)

在示例中,我们将add()square()函数应用于整数值列表。

for i in nums:

    vals = list(map(lambda x: x(i), (add, square)))

    print(vals)

我们遍历for循环中的元素。 在每个循环中,我们创建两个值的列表,这些值是通过对值应用add()square()函数来计算的。

$ ./python_map_multiple_funcs.py 
[2, 1]
[4, 4]
[6, 9]
[8, 16]
[10, 25]

第一个值通过加法形成,第二个值通过乘法形成。

Python 列表推导式

Python map()的功能也可以通过 Python 列表推导式来实现。

python_list_comprehension.py

#!/usr/bin/python3

def square(x):

    return x * x

nums = [1, 2, 3, 4, 5]

nums_squared = [square(num) for num in nums]

for num in nums_squared:

    print(num)

该示例使用 Python 列表推导式从整数列表创建平方值列表。

在本教程中,我们使用了 Python map()函数。

您可能也会对以下相关教程感兴趣: Python 教程Python 集教程Python 列表推导OpenPyXL 教程Python Requests 教程Python CSV 教程

Python CSV 教程-读写 CSV

原文: http://zetcode.com/python/csv/

Python CSV 教程显示了如何使用 Python csv 模块读取和写入 CSV 数据。

CSV

CSV(逗号分隔值)是在电子表格和数据库中使用的非常流行的导入和导出数据格式。 CSV 文件中的每一行都是一个数据记录。 每个记录由一个或多个字段组成,用逗号分隔。 CSV 是一种非常简单的数据格式,但是可以有很多差异,例如不同的定界符,换行或引号字符。

Python CSV 模块

csv模块实现用于以 CSV 格式读取和写入表格数据的类。 csv模块的readerwriter对象读取和写入序列。 程序员还可以使用DictReaderDictWriter类以字典形式读取和写入数据。

Python CSV 方法

下表显示了 Python csv 方法:

方法 描述
csv.reader 返回一个遍历 CSV 文件各行的读取器对象
csv.writer 返回将数据写入 CSV 文件的写入器对象
csv.register_dialect 注册 CSV 方言
csv.unregister_dialect 注销 CSV 方言
csv.get_dialect 返回具有给定名称的方言
csv.list_dialects 返回所有已注册的方言
csv.field_size_limit 返回解析器允许的当前最大字段大小

使用 Python csv模块

import csv

要使用 Python CSV 模块,我们导入csv

Python CSV 读取器

csv.reader()方法返回一个读取器对象,该对象遍历给定 CSV 文件中的行。

$ cat numbers.csv 
16,6,4,12,81,6,71,6

numbers.csv文件包含数字。

read_csv.py

#!/usr/bin/python3

import csv

f = open('numbers.csv', 'r')

with f:

    reader = csv.reader(f)

    for row in reader:
        for e in row:
            print(e)

在代码示例中,我们打开numbers.csv进行读取并读取其内容。

reader = csv.reader(f)

我们得到reader对象。

for row in reader:
    for e in row:
        print(e)

通过两个for循环,我们遍历数据。

$ ./read_csv.py 
16
6
4
12
81
6
71
6

这是示例的输出。

具有不同分隔符的 Python CSV 读取器

csv.reader()方法允许使用带有delimiter属性的不同定界符。

$ cat items.csv 
pen|cup|bottle
chair|book|tablet

items.csv包含用"|"分隔的字符值。

read_csv.py

#!/usr/bin/python3

import csv

f = open('items.csv', 'r')

with f:

    reader = csv.reader(f, delimiter="|")

    for row in reader:

        for e in row:            
            print(e)

该代码示例从使用'|'定界符的 CSV 文件读取并显示数据。

$ ./read_csv2.py 
pen
cup
bottle
chair
book
tablet

这是示例的输出。

Python CSV DictReader

csv.DictReader类的操作类似于常规读取器,但会将读取的信息映射到字典中。 字典的键可以使用fieldnames参数传入,也可以从 CSV 文件的第一行推断出来。

$ cat values.csv 
min,avg,max
1, 5.5, 10
2, 3.5, 5

文件的第一行包含字典键。

read_csv_dictionary.py

#!/usr/bin/python3

# read_csv3.py

import csv

f = open('values.csv', 'r')

with f:

    reader = csv.DictReader(f)

    for row in reader:
        print(row['min'], row['avg'], row['max'])

该示例使用csv.DictReadervalues.csv文件中读取值。

for row in reader:
    print(row['min'], row['avg'], row['max'] )

该行是 Python 字典,我们使用键引用数据。

Python CSV 编写器

csv.writer()方法返回一个writer对象,该对象将用户数据转换为给定文件状对象上的定界字符串。

write_csv.py

#!/usr/bin/python3

import csv

nms = [[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]]

f = open('numbers2.csv', 'w')

with f:

    writer = csv.writer(f)

    for row in nms:
        writer.writerow(row)

该脚本将数字写入numbers2.csv文件。 writerow()方法将一行数据写入指定的文件。

$ cat numbers2.csv 
1,2,3,4,5,6
7,8,9,10,11,12

一次写入所有数据是可能的。 writerows()方法将所有给定的行写入 CSV 文件。

write_csv2.py

#!/usr/bin/python3

import csv

nms = [[1, 2, 3], [7, 8, 9], [10, 11, 12]]

f = open('numbers3.csv', 'w')

with f:

    writer = csv.writer(f)
    writer.writerows(nms)

该代码示例使用writerows()方法将三行数字写入文件。

Python CSV DictWriter

csv.DictWriter类的操作类似于常规编写器,但将 Python 字典映射到 CSV 行。 fieldnames参数是一系列键,这些键标识传递给writerow()方法的字典中的值写入 CSV 文件的顺序。

write_csv_dictionary.py

#!/usr/bin/python3

import csv

f = open('names.csv', 'w')

with f:

    fnames = ['first_name', 'last_name']
    writer = csv.DictWriter(f, fieldnames=fnames)    

    writer.writeheader()
    writer.writerow({'first_name' : 'John', 'last_name': 'Smith'})
    writer.writerow({'first_name' : 'Robert', 'last_name': 'Brown'})
    writer.writerow({'first_name' : 'Julia', 'last_name': 'Griffin'})

该示例使用csv.DictWriter将 Python 字典中的值写入 CSV 文件。

writer = csv.DictWriter(f, fieldnames=fnames) 

创建了新的csv.DictWriter。 标头名称将传递给fieldnames参数。

writer.writeheader()

writeheader()方法将标头写入 CSV 文件。

writer.writerow({'first_name' : 'John', 'last_name': 'Smith'})

Python 字典被写入 CSV 文件中的一行。

$ cat names.csv 
first_name,last_name
John,Smith
Robert,Brown
Julia,Griffin

这是输出。

Python CSV 自定义方言

使用csv.register_dialect()方法创建自定义方言。

custom_dialect.py

#!/usr/bin/python3

import csv

csv.register_dialect("hashes", delimiter="#")

f = open('items3.csv', 'w')

with f:

    writer = csv.writer(f, dialect="hashes")
    writer.writerow(("pens", 4)) 
    writer.writerow(("plates", 2))
    writer.writerow(("bottles", 4))
    writer.writerow(("cups", 1))

该程序使用(# )字符作为分隔符。 使用csv.writer()方法中的dialect选项指定方言。

$ cat items3.csv 
pens#4
plates#2
bottles#4
cups#1

这是输出。

在本教程中,我们使用 Python 处理 CSV。

您可能也会对以下相关教程感兴趣: Python 教程Python 列表推导式PrettyTable 教程PyMongo 教程Python SimpleJson 教程OpenPyXL 教程Python Requests 教程Python 列表推导

Python 正则表达式

原文: http://zetcode.com/python/regularexpressions/

Python 正则表达式教程展示了如何在 Python 中使用正则表达式。 对于 Python 中的正则表达式,我们使用re模块。

正则表达式用于文本搜索和更高级的文本操作。 正则表达式是内置工具,如grepsed,文本编辑器(如 vi,emacs),编程语言(如 Tcl,Perl 和 Python)。

Python re模块

在 Python 中,re模块提供了正则表达式匹配操作。

模式是一个正则表达式,用于定义我们正在搜索或操纵的文本。 它由文本文字和元字符组成。 用compile()函数编译该模式。 由于正则表达式通常包含特殊字符,因此建议使用原始字符串。 (原始字符串以r字符开头。)这样,在将字符编译为模式之前,不会对这些字符进行解释。

编译模式后,可以使用其中一个函数将模式应用于文本字符串。 函数包括match()search()find()finditer()

下表显示了一些正则表达式:

正则表达式 含义
. 匹配任何单个字符。
? 一次匹配或根本不匹配前面的元素。
+ 与前面的元素匹配一次或多次。
* 与前面的元素匹配零次或多次。
^ 匹配字符串中的起始位置。
$ 匹配字符串中的结束位置。
| 备用运算符。
[abc] 匹配abc
[a-c] 范围; 匹配abc
[^abc] 否定,匹配除abc之外的所有内容。
\s 匹配空白字符。
\w 匹配单词字符; 等同于[a-zA-Z_0-9]

匹配函数

以下是一个代码示例,演示了 Python 中简单正则表达式的用法。

match_fun.py

#!/usr/bin/python3

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'book')

for word in words:
    if re.match(pattern, word):
        print('The {} matches '.format(word))

在示例中,我们有一个单词元组。 编译后的模式将在每个单词中寻找一个"book"字符串。

pattern = re.compile(r'book')

使用compile()函数,我们可以创建模式串。 正则表达式是一个原始字符串,由四个普通字符组成。

for word in words:
    if re.match(pattern, word):
        print('The {} matches '.format(word))

我们遍历元组并调用match()函数。 它将模式应用于单词。 如果字符串开头有匹配项,则match()函数将返回匹配对象。

$ ./match_fun.py 
The book matches 
The bookworm matches 
The bookish matches 
The bookstore matches 

元组中的四个单词与模式匹配。 请注意,以"book"一词开头的单词不匹配。 为了包括这些词,我们使用search()函数。

搜索函数

search()函数查找正则表达式模式产生匹配项的第一个位置。

search_fun.py

#!/usr/bin/python3

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'book')

for word in words:
    if re.search(pattern, word):
        print('The {} matches '.format(word))    

在示例中,我们使用search()函数查找"book"一词。

$ ./search_fun.py 
The book matches 
The bookworm matches 
The bookish matches 
The cookbook matches 
The bookstore matches 
The pocketbook matches 

这次还包括菜谱和袖珍书中的单词。

点元字符

点(。)元字符代表文本中的任何单个字符。

dot_meta.py

#!/usr/bin/python3

import re

words = ('seven', 'even', 'prevent', 'revenge', 'maven', 
    'eleven', 'amen', 'event')

pattern = re.compile(r'.even')

for word in words:
    if re.match(pattern, word):
        print('The {} matches '.format(word))

在示例中,我们有一个带有八个单词的元组。 我们在每个单词上应用一个包含点元字符的模式。

pattern = re.compile(r'.even')

点代表文本中的任何单个字符。 字符必须存在。

$ ./dot_meta.py 
The seven matches 
The revenge matches 

两个字匹配模式:七个和复仇。

问号元字符

问号(?)元字符是与上一个元素零或一次匹配的量词。

question_mark_meta.py

#!/usr/bin/python3

import re

words = ('seven', 'even','prevent', 'revenge', 'maven', 
    'eleven', 'amen', 'event')

pattern = re.compile(r'.?even')

for word in words:
    if re.match(pattern, word):
        print('The {} matches '.format(word))

在示例中,我们在点字符后添加问号。 这意味着在模式中我们可以有一个任意字符,也可以在那里没有任何字符。

$ ./question_mark_meta.py 
The seven matches 
The even matches 
The revenge matches 
The event matches 

这次,除了七个和复仇外,偶数和事件词也匹配。

锚点

锚点匹配给定文本内字符的位置。 当使用^锚时,匹配必须发生在字符串的开头,而当使用$锚时,匹配必须发生在字符串的结尾。

anchors.py

#!/usr/bin/python3

import re

sentences = ('I am looking for Jane.',
    'Jane was walking along the river.',
    'Kate and Jane are close friends.')

pattern = re.compile(r'^Jane')

for sentence in sentences:
    if re.search(pattern, sentence):
        print(sentence)

在示例中,我们有三个句子。 搜索模式为^Jane。 该模式检查"Jane"字符串是否位于文本的开头。 Jane\.将在句子结尾处查找"Jane"

fullmatch

可以使用fullmatch()函数或通过将术语放在锚点之间来进行精确匹配:^和$。

exact_match.py

#!/usr/bin/python3

import re

words = ('book', 'bookworm', 'Bible', 
    'bookish','cookbook', 'bookstore', 'pocketbook')

pattern = re.compile(r'^book$')

for word in words:
    if re.search(pattern, word):
        print('The {} matches'.format(word))    

在示例中,我们寻找与"book"一词完全匹配的内容。

$ ./exact_match.py 
The book matches

这是输出。

字符类

字符类定义了一组字符,任何字符都可以出现在输入字符串中以使匹配成功。

character_class.py

#!/usr/bin/python3

import re

words = ('a gray bird', 'grey hair', 'great look')

pattern = re.compile(r'gr[ea]y')

for word in words:
    if re.search(pattern, word):
        print('{} matches'.format(word))    

在该示例中,我们使用字符类同时包含灰色和灰色单词。

pattern = re.compile(r'gr[ea]y')

[ea]类允许在模式中使用'e'或'a'字符。

命名字符类

有一些预定义的字符类。 \s与空白字符[\t\n\t\f\v]匹配,\d与数字[0-9]匹配,\w与单词字符[a-zA-Z0-9_]匹配。

named_character_class.py

#!/usr/bin/python3

import re

text = 'We met in 2013\. She must be now about 27 years old.'

pattern = re.compile(r'\d+')

found = re.findall(pattern, text)

if found:
    print('There are {} numbers'.format(len(found)))    

在示例中,我们计算文本中的数字。

pattern = re.compile(r'\d+')

\d+模式在文本中查找任意数量的数字集。

found = re.findall(pattern, text)

使用findall()方法,我们可以查找文本中的所有数字。

$ ./named_character_classes.py 
There are 2 numbers

这是输出。

不区分大小写的匹配

默认情况下,模式匹配区分大小写。 通过将re.IGNORECASE传递给compile()函数,我们可以使其不区分大小写。

case_insensitive.py

#!/usr/bin/python3

import re

words = ('dog', 'Dog', 'DOG', 'Doggy')

pattern = re.compile(r'dog', re.IGNORECASE)

for word in words:
    if re.match(pattern, word):
        print('{} matches'.format(word))

在示例中,无论大小写如何,我们都将模式应用于单词。

$ ./case_insensitive.py 
dog matches
Dog matches
DOG matches
Doggy matches

所有四个单词都与模式匹配。

交替

交替运算符|创建具有多种选择的正则表达式。

alternations.py

#!/usr/bin/python3

import re

words = ("Jane", "Thomas", "Robert",
    "Lucy", "Beky", "John", "Peter", "Andy")

pattern = re.compile(r'Jane|Beky|Robert')

for word in words:
    if re.match(pattern, word):
        print(word)

列表中有八个名称。

pattern = re.compile(r'Jane|Beky|Robert')

此正则表达式查找Jane"Beky""Robert"字符串。

查找方法

finditer()方法返回一个迭代器,该迭代器在字符串中的模式的所有不重叠匹配上产生匹配对象。

find_iter.py

#!/usr/bin/python3

import re

text = ('I saw a fox in the wood. The fox had red fur.')

pattern = re.compile(r'fox')

found = re.finditer(pattern, text)

for item in found:

    s = item.start()
    e = item.end()
    print('Found {} at {}:{}'.format(text[s:e], s, e))

在示例中,我们在文本中搜索"fox"一词。 我们遍历找到的匹配项的迭代器,并使用它们的索引进行打印。

s = item.start()
e = item.end()

start()end()方法分别返回起始索引和结束索引。

$ ./find_iter.py 
Found fox at 8:11
Found fox at 29:32

这是输出。

捕获组

捕获组是一种将多个字符视为一个单元的方法。 通过将字符放置在一组圆括号内来创建它们。 例如,(book)是包含'b', 'o', 'o', 'k'字符的单个组。

捕获组技术使我们能够找出字符串中与常规模式匹配的那些部分。

capturing_groups.py

#!/usr/bin/python3

import re

content = '''<p>The <code>Pattern</code> is a compiled
representation of a regular expression.</p>'''

pattern = re.compile(r'(</?[a-z]*>)')

found = re.findall(pattern, content)

for tag in found:
    print(tag)

该代码示例通过捕获一组字符来打印提供的字符串中的所有 HTML 标签。

found = re.findall(pattern, content)

为了找到所有标签,我们使用findall()方法。

$ ./capturing_groups.py 
<p>
<code>
</code>
</p>

我们找到了四个 HTML 标签。

Python 正则表达式电子邮件示例

在以下示例中,我们创建一个用于检查电子邮件地址的正则表达式模式。

emails.py

#!/usr/bin/python3

import re

emails = ("luke@gmail.com", "andy@yahoocom", 
    "34234sdfa#2345", "f344@gmail.com")

pattern = re.compile(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,18}$')

for email in emails:
    if re.match(pattern, email):
        print("{} matches".format(email))
    else:
        print("{} does not match".format(email))

本示例提供了一种可能的解决方案。

pattern = re.compile(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\.[a-zA-Z.]{2,18}$')    

^和后$个字符提供精确的模式匹配。 模式前后不允许有字符。 电子邮件分为五个部分。 第一部分是本地部分。 这通常是公司,个人或昵称的名称。 [a-zA-Z0-9._-]+列出了所有可能的字符,我们可以在本地使用。 它们可以使用一次或多次。

第二部分由文字@字符组成。 第三部分是领域部分。 通常是电子邮件提供商的域名,例如 yahoo 或 gmail。 [a-zA-Z0-9-]+是一个字符类,提供可在域名中使用的所有字符。 +量词允许使用这些字符中的一个或多个。

第四部分是点字符。 它前面带有转义字符(\),以获取文字点。

最后一部分是顶级域:[a-zA-Z.]{2,18}。 顶级域可以包含 2 到 18 个字符,例如sk, net, info, travel, cleaning, travelinsurance。 最大长度可以为 63 个字符,但是今天大多数域都少于 18 个字符。 还有一个点字符。 这是因为某些顶级域包含两个部分: 例如co.uk

$ ./emails.py 
luke@gmail.com matches
andy@yahoocom does not match
34234sdfa#2345 does not match
f344@gmail.com matches

这是输出。

在本章中,我们介绍了 Python 中的正则表达式。

您可能也对以下相关教程感兴趣: Python CSV 教程Python 教程

Python SimpleJson 教程

原文: http://zetcode.com/python/simplejson/

Python SimpleJson 教程展示了如何使用 Python SimpleJson 模块读取和写入 JSON 数据。

JSON 格式

JSON(JavaScript 对象表示法)是一种轻量级的数据交换格式。 它很容易被人读写,也可以由机器解析和生成。 application/json是 JSON 的官方互联网媒体类型。 JSON 文件扩展名是.json

SimpleJson 模块

SimpleJson 是适用于 Python 2.5+和 Python 3.3+的简单,快速,完整且可扩展的 JSON 编码器和解码器。 它是没有依赖项的纯 Python 代码。

SimpleJson 模块包含在现代 Python 版本中。 解码器可以处理任何指定编码的传入 JSON 字符串(默认为 UTF-8)

使用 SimpleJson

import json

要使用 SimpleJson 模块,我们导入json

SimpleJson 转换表

下表显示了如何在 Python 和 JSON 之间转换数据类型。

Python JSON 格式
字典,命名元组 对象
列表,元组 数组
strunicode 字符串
intlongfloat 数字
True true
False false
None null

json.dump()

json.dump()方法将 Python 对象作为 JSON 格式的流序列化到文件对象。

simplejson_dump.py

#!/usr/bin/python

import json

data = {"name": "Jane", "age": 17}

with open('friends.json', 'w') as f:

    json.dump(data, f)

该示例使用json.dump()方法将 Python 字典序列化为 JSON。 JSON 数据被写入friends.json文件。

$ cat friends.json 
{"age": 17, "name": "Jane"}

执行脚本后,我们得到了这些数据。

json.dumps()

json.dumps()方法将 Python 对象序列化为 JSON 字符串。

simplejson_dumps.py

#!/usr/bin/python

import json

data = [{"name": "Jane", "age": 17}, {"name": "Thomas", "age": 27}]

json_data = json.dumps(data)
print(repr(json_data))

该示例使用json.dumps()方法将 Python 列表序列化为 JSON 字符串。 JSON 数据被打印到控制台。

$ ./simplejson_dumps.py 
'[{"name": "Jane", "age": 17}, {"name": "Thomas", "age": 27}]'

这是示例的输出。

json.load()

json.load()方法将包含 JSON 文档的文件对象反序列化为 Python 对象。

config.json

{
  "theme" : "bluespring",
  "size": "small",
  "splashscreen": "false"
}

config.json文件包含此数据。

read_config.py

#!/usr/bin/python

import json

with open('config.json') as f:

    config = json.load(f)

    print('Theme: {}'.format(config['theme']))
    print('Size: {}'.format(config['size']))
    print('Splash screen: {}'.format(config['splashscreen']))

该示例使用json.load()config.json文件读取配置数据,并将数据打印到终端。

$ ./read_config.py 
Theme: bluespring
Size: small
Splash screen: false

这是输出。

json.loads()

json.loads()方法将 JSON 字符串反序列化为 Python 对象。

simplejson_loads.py

#!/usr/bin/python

import json

json_data = '{"name": "Jane", "age": 17}'

data = json.loads(json_data)

print(type(json_data))
print(type(data))

print(data)

该示例将 JSON 字符串反序列化为 Python 字典。

$ ./simple.py 
<class 'str'>
<class 'dict'>
{'name': 'Jane', 'age': 17}

这是示例的输出。

SimpleJson 从 URL 读取 JSON

以下示例从网页读取 JSON 数据。 我们从http://time.jsontest.com获得 JSON 数据。

$ curl http://time.jsontest.com
{
   "time": "10:00:19 AM",
   "milliseconds_since_epoch": 1496311219347,
   "date": "06-01-2017"
}

对此站点的 GET 请求返回此 JSON 字符串。

parse_json_url.py

#!/usr/bin/python

import json
import urllib.request

hres = urllib.request.urlopen('http://time.jsontest.com')

data = json.loads(hres.read().decode("utf-8"))

print('Unix time: {}'.format(data['milliseconds_since_epoch']))
print('Time: {}'.format(data['time']))
print('Date: {}'.format(data['date']))

在该示例中,我们使用urllib.request模块创建对网站的请求。

data = json.loads(hres.read().decode("utf-8"))

从返回的响应中,我们使用json.loads()方法将 JSON 字符串转换为 Python 字典。

print('Unix time: {}'.format(data['milliseconds_since_epoch']))
print('Time: {}'.format(data['time']))
print('Date: {}'.format(data['date']))

借助 Python 的format()方法,我们将检索到的数据打印到控制台。

$ ./parse_json_url.py 
Unix time: 1496311518866
Time: 10:05:18 AM
Date: 06-01-2017

这是输出。

精美打印

使用 SimpleJson,我们可以轻松精美打印数据。

pretty_print_json.py

#!/usr/bin/python

import json

json_data = {"name":"Audi", "model":"2012", "price":22000, 
                 "colours":["gray", "red", "white"]}

data = json.dumps(json_data, sort_keys=True, indent=4 * ' ')

print(data)

使用sort_keysindent选项,我们可以很好地格式化 JSON 数据。

$ ./pretty_print_json.py 
{
    "colours": [
        "gray",
        "red",
        "white"
    ],
    "model": "2012",
    "name": "Audi",
    "price": 22000
}

这是示例的输出。 数据缩进并对键进行排序。

SimpleJson 自定义类

SimpleJson 仅序列化和反序列化一些 Python 对象,这些对象在转换表中列出。 对于自定义 Python 对象,我们需要执行一些附加步骤。

custom_class.py

#!/usr/bin/python

import json

class Person(object):

    def __init__(self, name, age):

        self.name = name
        self.age = age

p = Person("Lucy", 23) 

json_data = json.dumps(p.__dict__)

print(repr(json_data))

在此示例中,我们将自定义对象序列化为 JSON。

json_data = json.dumps(p.__dict__)

诀窍是使用__dict__属性,该属性存储对象属性(名称和年龄)。

$ ./custom_class.py 
'{"name": "Lucy", "age": 23}'

这是输出。

自定义类的 SimpleJson 列表

在下一个示例中,我们显示如何序列化自定义类的列表。

custom_class_list.py

#!/usr/bin/python

import json

class Person(object):

    def __init__(self, name, age):

        self.name = name
        self.age = age

    def toJson(self):
        '''
        Serialize the object custom object
        '''
        return json.dumps(self, default=lambda o: o.__dict__, 
                sort_keys=True, indent=4)            

p1 = Person("Lucy", 23) 
p2 = Person("Thomas", 29)

people = []
people.append(json.loads(p1.toJson()))
people.append(json.loads(p2.toJson()))

json_data = json.dumps(people)

print(repr(json_data))

我们创建了一个toJson()方法来序列化该对象。

people = []
people.append(json.loads(p1.toJson()))
people.append(json.loads(p2.toJson()))

将对象添加到列表时,我们将调用toJson()方法。

$ ./custom_class_list.py 
'[{"age": 23, "name": "Lucy"}, {"age": 29, "name": "Thomas"}]'

这是示例的输出。

在本教程中,我们使用了 Python SimpleJson 库。

您可能也会对以下相关教程感兴趣: Python 教程Python 列表推导式Pyquery 教程OpenPyXL 教程,[Python Requests 教程和 Python CSV 教程

SymPy 教程

原文: http://zetcode.com/python/sympy/

SymPy 教程展示了如何使用 SymPy 模块在 Python 中进行符号计算。 这是对 SymPy 的简要介绍。

计算机代数系统(CAS)是一种数学软件,能够以类似于数学家和科学家的传统手动计算方式来处理数学表达式。

符号计算象征性地处理数学对象的计算。 数学对象是准确而非近似地表示的,具有未求值变量的数学表达式以符号形式保留。

SymPy

SymPy 是用于符号数学的 Python 库。 它旨在成为功能齐全的计算机代数系统。 SymPy 包括从基本符号算术到微积分,代数,离散数学和量子物理学的功能。 它可以在 LaTeX 中显示结果。

$ pip install sympy

SymPy 是使用pip install sympy命令安装的。

Rational

SymPy 具有用于处理有理数的Rational。 有理数是可以表示为两个整数(分子p和非零分母q)的商或分数p / q的任何数字。

rational_values.py

#!/usr/bin/env python

from sympy import Rational

r1 = Rational(1/10)
r2 = Rational(1/10)
r3 = Rational(1/10)

val = (r1 + r2 + r3) * 3
print(val.evalf())

val2 = (1/10 + 1/10 + 1/10) * 3
print(val2)

该示例使用有理数。

val = (r1 + r2 + r3) * 3
print(val.evalf())

该表达形式为符号形式。 我们使用evalf()方法对其进行求值。

$ rational_values.py
0.900000000000000
0.9000000000000001

注意,当不使用有理数时,输出中会有一个小错误。

SymPy pprint

pprint()用于在控制台上精美打印输出。 LaTeX 可以达到最佳效果,例如在 Jupyter 笔记本中。

prettify.py

#!/usr/bin/env python

from sympy import pprint, Symbol, exp, sqrt
from sympy import init_printing

init_printing(use_unicode=True)

x = Symbol('x')

a = sqrt(2)
pprint(a)
print(a)

print("------------------------")

c = (exp(x) ** 2)/2
pprint(c)
print(c)

程序会美化输出。

init_printing(use_unicode=True)

对于某些字符,我们需要启用 unicode 支持。

$ prettify.py
√2
sqrt(2)
------------------------
    2⋅x
ℯ
────
    2
exp(2*x)/2

这是输出。 请注意,使用 Jupyter 笔记本会提供更好的输出。

平方根

平方根是一个数字,乘以它会产生指定的数量。

square_root.py

#!/usr/bin/env python

from sympy import sqrt, pprint, Mul

x = sqrt(2)
y = sqrt(2)

pprint(Mul(x,  y, evaluate=False)) 
print('equals to ')
print(x * y)

程序输出一个包含平方根的表达式。

pprint(Mul(x,  y, evaluate=False))

我们使用evaluate属性推迟对乘法表达式的求值。

$ square_root.py
√2⋅√2
equals to
2

这是输出。

SymPy 符号

符号计算适用于符号,以后可以对其进行求值。 使用符号之前,必须在 SymPy 中定义符号。

def_sym.py

#!/usr/bin/env python

# ways to define symbols

from sympy import Symbol, symbols
from sympy.abc import x, y

expr = 2*x + 5*y
print(expr)

a = Symbol('a')
b = Symbol('b')

expr2 = a*b + a - b
print(expr2)

i, j = symbols('i j')
expr3 = 2*i*j + i*j
print(expr3) 

该程序显示了三种在 SymPy 中定义符号的方法。

from sympy.abc import x, y

可以从sympy.abc模块导入符号。 它将所有拉丁字母和希腊字母导出为符号,因此我们可以方便地使用它们。

a = Symbol('a')
b = Symbol('b')

可以用Symbol定义

i, j = symbols('i j')

可以使用symbols()方法定义多个符号。

SymPy 规范表达形式

SymPy 会自动将表达式转换为规范形式。 SymPy 仅执行廉价操作; 因此,表达式可能无法求值为最简单的形式。

canonical_form.py

#!/usr/bin/env python

from sympy.abc import a, b

expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3

print(expr)

我们有一个带有符号ab的表达式。 该表达可以容易地简化。

$ canonical_form.py
2*a*b + 3*a + 4*b

这是输出。

SymPy 扩展代数表达式

使用expand(),我们可以扩展代数表达式; 即该方法尝试消除幂和乘法。

expand.py

#!/usr/bin/env python

from sympy import expand, pprint
from sympy.abc import x

expr = (x + 1) ** 2

pprint(expr)

print('-----------------------')
print('-----------------------')

expr = expand(expr)
pprint(expr)

该程序扩展了一个简单的表达式。

$ expand.py
       2
(x + 1)
-----------------------
-----------------------
 2
x  + 2⋅x + 1

这是输出。

SymPy 简化表达式

可以使用simplify()将表达式更改为更简单的形式。

simplify.py

#!/usr/bin/env python

from sympy import sin, cos, simplify, pprint
from sympy.abc import x

expr = sin(x) / cos(x)

pprint(expr)

print('-----------------------')

expr = simplify(expr)
pprint(expr)

例如将sin(x)/sin(y)表达式简化为tan(x)

$ simplify.py
sin(x)
──────
cos(x)
-----------------------
tan(x)

这是输出。

SymPy 比较表达式

SymPy 表达式与equals()而不是==运算符进行比较。

expr_equality.py

#!/usr/bin/env python

from sympy import pprint, Symbol, sin, cos

x = Symbol('x')

a = cos(x)**2 - sin(x)**2
b = cos(2*x)

print(a.equals(b))

# we cannot use == operator
print(a == b)

该程序比较两个表达式。

print(a.equals(b))

我们用equals()比较两个表达式。 在应用该方法之前,SymPy 尝试简化表达式。

$ expr_equality.py
True
False

这是输出。

SymPy 求值表达式

可以通过替换符号来求值表达式。

evaluating.py

#!/usr/bin/env python

from sympy import pi

print(pi.evalf(30))

该示例将pi值求值为 30 个位。

$ evaluating.py
3.14159265358979323846264338328

这是输出。

evaluating2.py

#!/usr/bin/env python

from sympy.abc import a, b
from sympy import pprint

expr = b*a + -4*a + b + a*b + 4*a + (a + b)*3

print(expr.subs([(a, 3), (b, 2)]))

本示例通过用数字替换ab符号来求值表达式。

$ evaluating.py
3.14159265358979323846264338328

这是输出。

SymPy 求解方程

solve()solveset()求解方程。

solving.py

#!/usr/bin/env python

from sympy import Symbol, solve

x = Symbol('x')

sol = solve(x**2 - x, x)

print(sol)

该示例使用solve()解决了一个简单方程。

sol = solve(x**2 - x, x)

solve()的第一个参数是公式。 该公式以适合 SymPy 的特定形式编写; 即x**2 - x代替x**2 = x。 第二个参数是我们需要解决的符号。

$ solving.py
[0, 1]

该方程式有两个解:0 和 1。

或者,我们可以将Eq用于公式。

solving2.py

#!/usr/bin/env python

from sympy import pprint, Symbol, Eq, solve

x = Symbol('x')

eq1 = Eq(x + 1, 4)
pprint(eq1)

sol = solve(eq1, x)
print(sol)

该示例解决了一个简单的x + 1 = 4方程。

$ solving2.py
x + 1 = 4
[3]

这是输出。

solving3.py

#!/usr/bin/env python

from sympy.solvers import solveset
from sympy import Symbol, Interval, pprint

x = Symbol('x')

sol = solveset(x**2 - 1, x, Interval(0, 100))
print(sol)

使用solveset(),我们找到了给定间隔的解决方案。

$ solving3.py
{1}

这是输出。

SymPy 序列

序列是其中允许重复的对象的枚举集合。 序列可以是有限的或无限的。 元素的数量称为序列的长度。 与集合不同,同一元素可以在序列中的不同位置出现多次。 元素的顺序很重要。

sequence.py

#!/usr/bin/env python

from sympy import summation, sequence, pprint
from sympy.abc import x

s = sequence(x, (x, 1, 10))
print(s)
pprint(s)
print(list(s))

print(s.length)

print(summation(s.formula, (x, s.start, s.stop)))
# print(sum(list(s)))

本示例创建一个由数字 1、2,...,10 组成的序列。 我们计算这些数字的总和。

$ sequence.py
SeqFormula(x, (x, 1, 10))
[1, 2, 3, 4, …]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
10
55

这是输出。

SymPy 极限

极限是函数(或序列)“接近”作为输入(或索引)“接近”某个值的值。

limit.py

#!/usr/bin/env python

from sympy import sin, limit, oo
from sympy.abc import x

l1 = limit(1/x, x, oo)
print(l1)

l2 = limit(1/x, x, 0)
print(l2)

在示例中,我们具有1/x函数。 它具有左侧和右侧限制。

from sympy import sin, limit, sqrt, oo

oo表示无穷大。

l1 = limit(1/x, x, oo)
print(l1)

我们计算1/x的极限,其中x接近正无穷大。

$ limit.py
0
oo

这是输出。

SymPy 矩阵

在 SymPy 中,我们可以使用矩阵。 矩阵是数字或其他数学对象的矩形数组,为其定义了运算(例如加法和乘法)。

矩阵用于计算,工程或图像处理。

matrix.py

#!/usr/bin/env python

from sympy import Matrix, pprint

M = Matrix([[1, 2], [3, 4], [0, 3]])
print(M)
pprint(M)

N = Matrix([2, 2])

print("---------------------------")
print("M * N")
print("---------------------------")

pprint(M*N)

该示例定义了两个矩阵并将它们相乘。

$ matrix.py
Matrix([[1, 2], [3, 4], [0, 3]])
⎡1  2⎤
⎢    ⎥
⎢3  4⎥
⎢    ⎥
⎣0  3⎦
---------------------------
M * N
---------------------------
⎡6 ⎤
⎢  ⎥
⎢14⎥
⎢  ⎥
⎣6 ⎦

这是输出。

SymPy 绘图

SymPy 包含用于绘图的模块。 它基于 Matplotlib 构建。

simple_plot.py

#!/usr/bin/env python

# uses matplotlib

import sympy
from sympy.abc import x
from sympy.plotting import plot

plot(1/x)

该示例绘制了1/x函数的二维图。

这是 SymPy 教程。

您可能也对以下相关教程感兴趣: PrettyTable 教程Matplotlib 教程Python 教程

Pandas 教程

原文: http://zetcode.com/python/pandas/

这是 Pandas 的入门教程。 本教程展示了如何使用 Pandas 库在 Python 中进行基本数据分析。 代码示例和数据可在作者的 Github 仓库中获得。

Pandas

Pandas 是 BSD 许可的开放源代码库,为 Python 编程语言提供了高性能,易于使用的数据结构和数据分析工具。

库的名称来自“面板数据”一词,这是对数据集的计量经济学术语,其中包括对同一个人在多个时间段内的观察。

它提供用于操纵数值表和时间序列的数据结构和操作。 主要的两种数据类型是:SeriesDataFrame

DataFrame是带有标记轴(行和列)的二维大小可变的,可能是异构的表格数据结构。 它是一个类似于电子表格的数据结构。 SeriesDataFrame的单个列。 DataFrame可以看作是Series对象的字典。

安装 Pandas

使用以下命令安装 Pandas:

$ pip3 install pandas

我们使用pip3命令安装pandas模块。

$ pip3 install numpy

一些示例还使用numpy

Pandas 简单的例子

以下是一个简单的 Pandas 示例。

simple.py

#!/usr/bin/env python3

import pandas as pd

data = [['Alex', 10], ['Ronald', 18], ['Jane', 33]]
df = pd.DataFrame(data, columns=['Name', 'Age'])

print(df)

在程序中,我们创建一个简单的DataFrame并将其打印到控制台。

import pandas as pd

我们导入 Pandas 库。

data = [['Alex', 10], ['Ronald', 18], ['Jane', 33]]

这是要在框架中显示的数据。 每个嵌套列表在表中都是一行。 请注意,有很多方法可以初始化 Pandas DataFrame

df = pd.DataFrame(data, columns=['Name', 'Age'])

根据数据创建一个DataFrame。 我们用columns属性给框架列名。

$ python simple.py
    Name  Age
0    Alex   10
1  Ronald   18
2    Jane   33

这是输出。 第一列是行索引。

Pandas 改变索引

我们可以更新索引,使其不从 0 开始。

change_index.py

#!/usr/bin/env python3

import pandas as pd

data = [['Alex', 10], ['Ronald', 18], ['Jane', 33]]
df = pd.DataFrame(data, columns=['Name', 'Age'])
df.index = df.index + 1

print(df)

在示例中,我们将 1 加到索引。

$ python change_index.py
    Name  Age
1    Alex   10
2  Ronald   18
3    Jane   33

这是输出。

Pandas 标量序列

以下示例创建一系列标量值。

series_scalar.py

#!/usr/bin/env python3

import pandas as pd

s = pd.Series(5, index=[0, 1, 2, 3])
print(s)

我们有一列包含数字。

$ python series_scalar.py
0    5
1    5
2    5
3    5
dtype: int64

左列是索引。

Pandas 序列ndarray

我们可以从 numpy ndarray 创建一个系列对象。

series_numpy.py

#!/usr/bin/env python3

import pandas as pd
import numpy as np

data = np.array(['a', 'b', 'c', 'd'])
s = pd.Series(data)

print(s)

该示例从ndarray创建一列字母。

$ python series_numpy.py
0    a
1    b
2    c
3    d
dtype: object

这是输出。

Pandas 序列字典

可以从 Python 字典创建系列。

series_dict.py

#!/usr/bin/env python3

import pandas as pd
import numpy as np

data = {'coins' : 22, 'pens' : 3, 'books' : 28}
s = pd.Series(data)

print(s)

该示例根据一系列项目创建一个系列对象。

$ python series_dict.py
coins    22
pens      3
books    28
dtype: int64

索引由项目名称组成。

Pandas 序列检索

以下示例从一系列对象中检索值。

series_retrieve.py

#!/usr/bin/env python3

import pandas as pd

s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])

print(s[0])
print('-----------------------')

print(s[1:4])
print('-----------------------')

print(s[['a','c','d']])

该示例从系列对象检索值。

print(s[0])

在这里,我们得到一个值。

print(s[1:4])

我们通过它们的索引检索行。

print(s[['a','c','d']])

在这里,我们通过索引标签获取值。

$ python series_retrieve.py
1
-----------------------
b    2
c    3
d    4
dtype: int64
-----------------------
a    1
c    3
d    4
dtype: int64

这是输出。

Pandas 自定义索引

索引列不必是数字。 我们可以创建自己的自定义索引。

custom_index.py

#!/usr/bin/env python3

import pandas as pd

data = {"country": ["Brazil", "Russia", "India", "China", "South Africa"],
        "capital": ["Brasilia", "Moscow", "New Dehli", "Beijing", "Pretoria"],
        "area": [8.516, 17.10, 3.286, 9.597, 1.221],
        "population": [200.4, 143.5, 1252, 1357, 52.98]}

frame = pd.DataFrame(data)
print(frame)

print('------------------------------')

frame.index = ["BR", "RU", "IN", "CH", "SA"]
print(frame)

在示例中,我们从数据字典创建数据框架。 我们先打印数据框,然后使用index属性更改索引列。

$ python custom_index.py
        country    capital    area  population
0        Brazil   Brasilia   8.516      200.40
1        Russia     Moscow  17.100      143.50
2         India  New Dehli   3.286     1252.00
3         China    Beijing   9.597     1357.00
4  South Africa   Pretoria   1.221       52.98
------------------------------
         country    capital    area  population
BR        Brazil   Brasilia   8.516      200.40
RU        Russia     Moscow  17.100      143.50
IN         India  New Dehli   3.286     1252.00
CH         China    Beijing   9.597     1357.00
SA  South Africa   Pretoria   1.221       52.98

这是输出。

Pandas 索引、列和值

PandasDataFrame具有三个基本部分:索引,列和值。

index_vals_cols.py

#!/usr/bin/env python3

import pandas as pd

data = [['Alex', 10], ['Ronald', 18], ['Jane', 33]]
df = pd.DataFrame(data, columns=['Name', 'Age'])

print(f'Index: {df.index}')
print(f'Columns: {df.columns}')
print(f'Values: {df.values}')

该示例显示数据框的索引,列和值。

$ python index_vals_cols.py
Index: RangeIndex(start=0, stop=3, step=1)
Columns: Index(['Name', 'Age'], dtype='object')
Values: [['Alex' 10]
    ['Ronald' 18]
    ['Jane' 33]]

这是输出。

Pandas 的总和和最大值

下面的示例计算数据帧列中值的总和和最大值。 它还使用numpy库。

sum_max.py

#!/usr/bin/env python3

import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(0, 1200, 2), columns=['A'])
# df.index = df.index + 1

print(sum(df['A']))
print(max(df['A']))

# print(df)

该示例计算最大值和值之和。 它使用numpyarange()函数生成值数组。

print(sum(df['A']))

当计算总和值时,我们通过名称来引用该列。

$ sum_max.py
359400
1198

这是输出。

Pandas 读 CSV

Pandas 使用read_csv()从 CSV 文件读取数据。

military_spending.csv

Pos, Country, Amount (Bn. $), GDP
1, United States, 610.0, 3.1
2, China, 228.0, 1.9
3, Saudi Arabia, 69.4, 10.0
4, Russia, 66.3, 4.3
5, India, 63.9, 2.5
6, France, 57.8, 2.3
7, United Kingdom, 47.2, 1.8
8, Japan, 45.4, 0.9
9, Germany, 44.3, 1.2
10, South Korea, 39.2, 2.6
11, Brazil, 29.3, 1.4
12, Italy Italy, 29.2, 1.5
13, Australia Australia, 27.5, 2.0
14, Canada Canada, 20.6, 1.3
15, Turkey Turkey, 18.2, 2.2

这是一个简单的 CSV 文件,其中包含有关国家军事支出的数据。

注意:CSV 文件在第一行中可能具有可选的列名。

read_from_csv.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("military_spending.csv")

print(df.to_string(index=False))

该示例从military_spending.csv文件中读取所有数据,并以表格格式将其打印到控制台。 它使用read_csv()方法。

print(df.to_string(index=False))

由于我们有positions列,因此我们从输出中隐藏索引。

$ python read_from_csv.py
Pos               Country   Amount (Bn. $)   GDP
  1         United States            610.0   3.1
  2                 China            228.0   1.9
  3          Saudi Arabia             69.4  10.0
  4                Russia             66.3   4.3
  5                 India             63.9   2.5
  6                France             57.8   2.3
  7        United Kingdom             47.2   1.8
  8                 Japan             45.4   0.9
  9               Germany             44.3   1.2
 10           South Korea             39.2   2.6
 11                Brazil             29.3   1.4
 12           Italy Italy             29.2   1.5
 13   Australia Australia             27.5   2.0
 14         Canada Canada             20.6   1.3
 15         Turkey Turkey             18.2   2.2

这是输出。

Pandas 写 CSV

to_csv()DataFrame写入 CSV 文件。

write_csv.py

#!/usr/bin/env python3

import pandas as pd

data = [['Alex', 10], ['Ronald', 18], ['Jane', 33]]
df = pd.DataFrame(data, columns=['Name', 'Age'])

df.to_csv("users.csv", index=False)

该示例将数据写入users.csv文件。

Pandas 随机行

可以使用sample()选择数据帧中的随机行。

random_sample.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("military_spending.csv")

print(df.sample(3))

在该示例中,我们从数据框中打印了三个随机行。

Pandas 数据定位

to_dict()将数据框转换为 Python 字典。 字典可以显示在不同的数据输出中。

data_orient.py

#!/usr/bin/env python3

import pandas as pd

data = [['Alex', 10], ['Ronald', 18], ['Jane', 33]]
df = pd.DataFrame(data, columns=['Name', 'Age'])

print('list')
print(df.to_dict(orient='list'))

print('************************************')

print('series')
print(df.to_dict(orient='series'))

print('************************************')

print('dict')
print(df.to_dict(orient='dict'))

print('************************************')

print('split')
print(df.to_dict(orient='split'))

print('************************************')

print('records')
print(df.to_dict(orient='records'))

print('************************************')

print('index')
print(df.to_dict(orient='index'))

该示例以六种不同格式将数据帧打印到控制台。

Pandas 描述

describe()方法生成描述性统计数据,该数据统计总结了NaN值之外的数据集分布的集中趋势,离散度和形状。

describing.py

#!/usr/bin/env python3

import pandas as pd

s1 = pd.Series([1, 2, 3, 4, 5, 6, 7, 8])
s2 = pd.Series([12, 23, 31, 14, 11, 61, 17, 18])

data = {'Vals 1': s1, 'Vals 2': s2}
df = pd.DataFrame(data)

print(df.describe())

该示例从数据框中打印描述性统计信息。

$ python describe.py
        Vals 1     Vals 2
count  8.00000   8.000000
mean   4.50000  23.375000
std    2.44949  16.535136
min    1.00000  11.000000
25%    2.75000  13.500000
50%    4.50000  17.500000
75%    6.25000  25.000000
max    8.00000  61.000000

这是输出。

Pandas 计数

下一个示例对值进行计数。 您可以在 Github 仓库中找到employees.csv文件。

counting.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("employees.csv")

print(df.count())

print(f'Number of columns: {len(df.columns)}')

print(df.shape)

count()方法计算每列的值数。 用len(df.columns)检索列数。 shape返回表示数据帧维数的元组。

$ python counting.py
First Name            933
Gender                855
Start Date           1000
Last Login Time      1000
Salary               1000
Bonus %              1000
Senior Management     933
Team                  957
dtype: int64
Number of columns: 8
(1000, 8)

请注意,这些列具有不同数量的值,因为缺少某些值。

Pandas head()tail()

使用head()tail()方法,我们可以显示数据帧的前 n 行和后 n 行。

head_tail.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("military_spending.csv")

print(df.head(4))

print('*******************************************')

print(df.tail(4))

该示例显示数据框的前四行和后四行。

$ python head_tail.py
Pos         Country   Amount (Bn. $)   GDP
0    1   United States            610.0   3.1
1    2           China            228.0   1.9
2    3    Saudi Arabia             69.4  10.0
3    4          Russia             66.3   4.3
*******************************************
 Pos               Country   Amount (Bn. $)   GDP
11   12           Italy Italy             29.2   1.5
12   13   Australia Australia             27.5   2.0
13   14         Canada Canada             20.6   1.3
14   15         Turkey Turkey             18.2   2.2

这是输出。

Pandas 没有标题和索引

当我们显示数据框时,我们可以隐藏标题和索引。

no_header_index.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("military_spending.csv")

print(df.head(4).to_string(header=False, index=False))

通过将headerindex属性设置为False,我们将输出没有标题和索引的数据帧。

$ python no_header.py
1   United States  610.0   3.1
2           China  228.0   1.9
3    Saudi Arabia   69.4  10.0
4          Russia   66.3   4.3

这是输出。 (值 1 到 4 来自pos列。)

Pandas loc()

loc()方法允许按标签或布尔数组访问一组行和列。

select_loc.py

#!/usr/bin/env python3

import pandas as pd

data = {'Items': ['coins', 'pens', 'books'], 'Quantity': [22, 28, 3]}

df = pd.DataFrame(data, index=['A', 'B', 'C'])

print(df.loc['A'])

print('-------------------------------')

print(df.loc[['A', 'B'], ['Items']])

该示例使用loc()函数。

print(df.loc['A'])

在这里,我们得到第一行。 我们通过其索引标签访问该行。

print(df.loc[['A', 'B'], ['Items']])

在这里,我们获得了Items列的前两行。

$ python select_loc.py
Items       coins
Quantity       22
Name: A, dtype: object
-------------------------------
    Items
A  coins
B   pens

这是输出。

第二个示例显示如何通过布尔数组选择。

select_loc2.py

#!/usr/bin/env python3

import pandas as pd

data = {'Items': ['coins', 'pens', 'books'], 'Quantity': [22, 28, 3]}

df = pd.DataFrame(data, index=['A', 'B', 'C'])

print(df.loc[[True, False, True], ['Items', 'Quantity']])

该示例通过布尔数组选择行。

$ select_loc2.py
    Items  Quantity
 A  coins        22
 C  books         3

这是输出。

在第三个示例中,我们在选择时应用条件。

select_loc3.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("employees.csv")

data = df.loc[(df['Salary'] > 10000) & (df['Salary'] < 50000)]
print(data.head(5))

该示例从employees.csv文件中打印出符合条件的前五行:薪水在 10000 至 50000 之间。

Pandas iloc

iloc函数允许基于整数位置的索引,以按位置进行选择。

select_iloc.py

#!/usr/bin/env python3

import pandas as pd

df = pd.read_csv("employees.csv")

# integer-location based indexing for selection by position.
# Multiple row and column selections using iloc and DataFrame

print(df.iloc[0:6])  # first six rows of dataframe
print('--------------------------------------')

print(df.iloc[:, 0:2])  # first two columns of data frame with all rows
print('--------------------------------------')

# 1st, 4th, 7th, 25th row + 1st 6th 8th column
print(df.iloc[[0, 3, 6, 24], [0, 5, 7]])
print('--------------------------------------')

# first 5 rows and 5th, 6th, 7th columns of data frame
print(df.iloc[:5, 5:8])
print('--------------------------------------')

该示例显示了如何使用iloc()选择行和列的各种组合。

Pandas 排序

sort_values()按升序或降序对系列进行排序。

sorting.py

#!/usr/bin/env python3

import pandas as pd

s1 = pd.Series([2, 1, 4, 5, 3, 8, 7, 6])
s2 = pd.Series([12, 23, 31, 14, 11, 61, 17, 18])

data = {'Col 1': s1, 'Col 2': s2}
df = pd.DataFrame(data)

print(df.sort_values('Col 1', ascending=True))
print('------------------------------------')
print('Sorted')

print(df.sort_values('Col 2', ascending=False))

该示例按升序或降序对列进行排序。

$ python sorting.py
    Col 1  Col 2
 1      1     23
 0      2     12
 4      3     11
 2      4     31
 3      5     14
 7      6     18
 6      7     17
 5      8     61
 ------------------------------------
 Sorted
    Col 1  Col 2
 5      8     61
 2      4     31
 1      1     23
 7      6     18
 6      7     17
 3      5     14
 0      2     12
 4      3     11

这是输出。

在下一个示例中,我们按多列排序。

sorting2.py

#!/usr/bin/env python3

import pandas as pd

s1 = pd.Series([1, 2, 1, 2, 2, 1, 2, 2])
s2 = pd.Series(['A', 'A', 'B', 'A', 'C', 'C', 'C', 'B'])

data = {'Col 1': s1, 'Col 2': s2}
df = pd.DataFrame(data)

print(df.sort_values(['Col 1', 'Col 2'], ascending=[True, False]))

该示例按包含整数的第一列进行排序。 然后,将考虑第一排序的结果对第二列进行排序。

$ python sorting2.py
    Col 1 Col 2
 5      1     C
 2      1     B
 0      1     A
 4      2     C
 6      2     C
 7      2     B
 1      2     A
 3      2     A

这是输出。

在本教程中,我们使用了 Pandas 库。

您可能也对以下相关教程感兴趣: Python 教程OpenPyXL 教程Python Requests 教程Python CSV 教程, 或列出所有 Python 教程

Matplotlib 教程

原文: http://zetcode.com/python/matplotlib/

Matplotlib 教程展示了如何使用 Matplotlib 在 Python 中创建图表。 我们创建散点图,折线图,条形图和饼图。

Matplotlib

Matplotlib 是用于创建图表的 Python 库。 Matplotlib 可用于 Python 脚本,Python 和 IPython shell,jupyter 笔记本,Web 应用服务器以及四个图形用户界面工具包。

Matplotlib 安装

Matplotlib 是需要安装的外部 Python 库。

$ sudo pip install matplotlib

我们可以使用pip工具安装该库。

Matplotlib 散点图

散点图是一种图形或数学图,使用笛卡尔坐标显示一组数据的两个变量的值。

scatter.py

#!/usr/bin/python3

import matplotlib.pyplot as plt

x_axis = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_axis = [5, 16, 34, 56, 32, 56, 32, 12, 76, 89]

plt.title("Prices over 10 years")
plt.scatter(x_axis, y_axis, color='darkblue', marker='x', label="item 1")

plt.xlabel("Time (years)")
plt.ylabel("Price (dollars)")

plt.grid(True)
plt.legend()

plt.show()

该示例绘制了一个散点图。 该图表显示了十年内某些商品的价格。

import matplotlib.pyplot as plt

我们从matplotlib模块导入pyplot。 它是创建图表的命令样式函数的集合。 它的操作与 MATLAB 类似。

x_axis = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_axis = [5, 16, 34, 56, 32, 56, 32, 12, 76, 89]

我们有 x 和 y 轴的数据。

plt.title("Prices over 10 years")

通过title()函数,我们可以为图表设置标题。

plt.scatter(x_axis, y_axis, color='darkblue', marker='x', label="item 1")

scatter()函数绘制散点图。 它接受 x 和 y 轴,标记的颜色,标记的形状和标签的数据。

plt.xlabel("Time (years)")
plt.ylabel("Price (dollars)")

我们为轴设置标签。

plt.grid(True)

我们用grid()函数显示网格。 网格由许多垂直和水平线组成。

plt.legend()

legend()函数在轴上放置图例。

plt.show()

show()函数显示图表。

Scatter chart

图:散点图

两个数据集

在下一个示例中,我们将另一个数据集添加到图表。

scatter2.py

#!/usr/bin/python3

import matplotlib.pyplot as plt

x_axis1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_axis1 = [5, 16, 34, 56, 32, 56, 32, 12, 76, 89]

x_axis2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_axis2 = [53, 6, 46, 36, 15, 64, 73, 25, 82, 9] 

plt.title("Prices over 10 years")

plt.scatter(x_axis1, y_axis1, color='darkblue', marker='x', label="item 1")
plt.scatter(x_axis2, y_axis2, color='darkred', marker='x', label="item 2")

plt.xlabel("Time (years)")
plt.ylabel("Price (dollars)")

plt.grid(True)
plt.legend()

plt.show()

该图表显示两个数据集。 我们通过标记的颜色来区分它们。

x_axis1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_axis1 = [5, 16, 34, 56, 32, 56, 32, 12, 76, 89]

x_axis2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_axis2 = [53, 6, 46, 36, 15, 64, 73, 25, 82, 9] 

我们有两个数据集。

plt.scatter(x_axis1, y_axis1, color='darkblue', marker='x', label="item 1")
plt.scatter(x_axis2, y_axis2, color='darkred', marker='x', label="item 2")

我们为每个集合调用scatter()函数。

Matplotlib 折线图

折线图是一种显示图表的图表,该信息显示为一系列数据点,这些数据点通过直线段相连,称为标记。

linechart.py

#!/usr/bin/python3

import numpy as np
import matplotlib.pyplot as plt

t = np.arange(0.0, 3.0, 0.01)
s = np.sin(2.5 * np.pi * t)
plt.plot(t, s)

plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')

plt.title('Sine Wave')
plt.grid(True)

plt.show()

该示例显示正弦波折线图。

import numpy as np

在示例中,我们还需要numpy模块。

t = np.arange(0.0, 3.0, 0.01)

arange()函数返回给定间隔内的均匀间隔的值列表。

s = np.sin(2.5 * np.pi * t)

我们获得数据的sin()值。

plt.plot(t, s)

我们使用plot()函数绘制折线图。

Matplotlib 条形图

条形图显示带有矩形条的分组数据,其长度与它们代表的值成比例。 条形图可以垂直或水平绘制。

barchart.py

#!/usr/bin/python3

from matplotlib import pyplot as plt
from matplotlib import style

style.use('ggplot')

x = [0, 1, 2, 3, 4, 5]
y = [46, 38, 29, 22, 13, 11]

fig, ax = plt.subplots()

ax.bar(x, y, align='center')

ax.set_title('Olympic Gold medals in London')
ax.set_ylabel('Gold medals')
ax.set_xlabel('Countries')

ax.set_xticks(x)
ax.set_xticklabels(("USA", "China", "UK", "Russia", 
    "South Korea", "Germany"))

plt.show()

该示例绘制了条形图。 它显示了 2012 年伦敦每个国家/地区的奥运金牌数量。

style.use('ggplot')

可以使用预定义的样式。

fig, ax = plt.subplots()

subplots()函数返回图形和轴对象。

ax.bar(x, y, align='center')

使用bar()函数生成条形图。

ax.set_xticks(x)
ax.set_xticklabels(("USA", "China", "UK", "Russia", 
    "South Korea", "Germany"))

我们为 x 轴设置国家/地区名称。

Matplotlib 饼图

饼图是圆形图,将其分成多个切片以说明数值比例。

piechart.py

#!/usr/bin/python3

import matplotlib.pyplot as plt

labels = ['Oranges', 'Pears', 'Plums', 'Blueberries']
quantity = [38, 45, 24, 10]

colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']

plt.pie(quantity, labels=labels, colors=colors, autopct='%1.1f%%', 
    shadow=True, startangle=90)

plt.axis('equal')

plt.show()

该示例创建一个饼图。

labels = ['Oranges', 'Pears', 'Plums', 'Blueberries']
quantity = [38, 45, 24, 10]

我们有标签和相应的数量。

colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral']

我们为饼图的切片定义颜色。

plt.pie(quantity, labels=labels, colors=colors, autopct='%1.1f%%', 
    shadow=True, startangle=90)

饼图是通过pie()函数生成的。 autopct负责在图表的楔形图中显示百分比。

plt.axis('equal')

我们设置了相等的长宽比,以便将饼图绘制为圆形。

Pie chart

图:饼图

在本教程中,我们使用 Matplotlib 库创建了散点图,折线图,条形图和饼图。

您可能也对以下相关教程感兴趣: PrettyTable 教程Tkinter 教程SymPy 教程Python Pillow 教程PyQt5 教程Python 教程

Pillow 教程

原文: http://zetcode.com/python/pillow/

Pillow 教程展示了如何在 Python 中使用 Pillow 来处理图像。 来源可从作者的 Github 仓库中获得。

Pillow

Pillow 是 Python 图像库(PIL),它增加了对打开,操作和保存图像的支持。 当前版本标识并读取大量格式。 有意将写支持限制为最常用的交换和表示格式。

显示图片

在第一个示例中,我们读取图像文件并在外部程序中显示它。

show_image.py

#!/usr/bin/python3

from PIL import Image
import sys

try:
    tatras = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")
    sys.exit(1)

tatras.show()

该程序读取 JPG 图像并将其显示在外部应用中。

from PIL import Image

在 PIL 模块中,我们包含Image类。

tatras = Image.open("tatras.jpg")

Image.open()方法读取图像文件。Pillow 可以读取 30 多种不同的文件格式。

tatras.show()

show()方法主要用于调试目的。 它将图像保存到一个临时文件中并在外部程序中显示。 在 Linux 上可以是 ImageMagic,在 Windows 上可以是 Paint。

Pillow 的基本图像信息

Pillow 使我们可以获得有关图像的一些基本信息。

basic_info.py

#!/usr/bin/python3

from PIL import Image
import sys

try:
    tatras = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")
    sys.exit(1)

print("Format: {0}\nSize: {1}\nMode: {2}".format(tatras.format, 
    tatras.size, tatras.mode))

该示例使用 Pillow 打印有关图像的基本信息。

print("Format: {0}\nSize: {1}\nMode: {2}".format(tatras.format, 
    tatras.size, tatras.mode)) 

我们打印图像格式,大小和模式。

$ ./basic_info.py 
Format: JPEG
Size: (350, 232)
Mode: RGB

这是程序的输出。

图像模糊

ImageFilter模块包含一组预定义的过滤器的定义,可以与filter()方法一起使用。

blur_image.py

#!/usr/bin/python3

from PIL import Image, ImageFilter
import sys

try:
    img = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")    
    sys.exit(1)

blurred = img.filter(ImageFilter.BLUR)

blurred.save("blurred.png")

该程序加载图像,从原始图像创建模糊图像,然后将新图像保存在磁盘上。

from PIL import Image, ImageFilter

我们导入ImageImageFilter模块。

blurred = img.filter(ImageFilter.BLUR)

我们将ImageFilter.BLUR应用于原始图像; 该操作将返回一个新的修改图像。

blurred.save("blurred.png")

使用save()方法,我们将模糊的图像保存在磁盘上。

用 Pillow 转换图像

使用save()方法,我们可以将图像转换为其他格式。

convert2png.py

#!/usr/bin/python3

from PIL import Image
import sys

try:
    tatras = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")
    sys.exit(1)

tatras.save('tatras.png', 'png')  

该程序读取 JPG 图像并将其转换为 PNG 格式。

tatras.save('tatras.png', 'png')  

save()方法的第二个参数指定图像格式。

灰度图像

使用Image.convert()方法,我们可以产生黑白图像。

grayscale.py

#!/usr/bin/python3

from PIL import Image
import sys

try:
    tatras = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")
    sys.exit(1)

grayscale = tatras.convert('L')
grayscale.show()

该程序读取图像并将其转换为灰度图像。

grayscale = tatras.convert('L')

convert()方法的第一个参数是mode"L"模式是黑白的。

用 Pillow 裁剪图像

Image.crop()裁剪图像。

crop_image.py

#!/usr/bin/python3

from PIL import Image
import sys

try:
    tatras = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")
    sys.exit(1)

cropped = tatras.crop((100, 100, 350, 350))
cropped.save('tatras_cropped.jpg')

该程序将裁剪图像。 裁剪后的图像保存在磁盘上。

cropped = tatras.crop((100, 100, 350, 350))

crop()方法采用 4 个元组来定义左,上,右和下像素坐标。

用 Pillow 旋转图像

Image.rotate()返回图像的旋转副本。

rotate_image.py

#!/usr/bin/python3

from PIL import Image
import sys

try:
    tatras = Image.open("tatras.jpg")

except IOError:
    print("Unable to load image")
    sys.exit(1)

rotated = tatras.rotate(180)
rotated.save('tatras_rotated.jpg') 

该程序将图像旋转 180 度并将新创建的图像保存在磁盘上。

在 Tkinter 中显示图像

以下程序在 Tkinter 程序中显示图像。

show_tkinter.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

from PIL import Image, ImageTk
from tkinter import Tk
from tkinter.ttk import Frame, Label
import sys

class Example(Frame):

    def __init__(self):
        super().__init__()   

        self.loadImage() 
        self.initUI()

    def loadImage(self):
        try:
            self.img = Image.open("tatrs.jpg")

        except IOError:
            print("Unable to load image")
            sys.exit(1)

    def initUI(self):

        self.master.title("Label")

        tatras = ImageTk.PhotoImage(self.img)
        label = Label(self, image=tatras)

        # reference must be stored
        label.image = tatras

        label.pack()
        self.pack()

    def setGeometry(self):

        w, h = self.img.size
        self.master.geometry(("%dx%d+300+300") % (w, h))

def main():

    root = Tk()
    ex = Example()
    ex.setGeometry()
    root.mainloop()  

if __name__ == '__main__':
    main()  

该程序在 Tkinter 工具箱的Label小部件中显示图像。

from PIL import Image, ImageTk

ImageTk是 Tkinter 兼容的照片图像。 它可以在 Tkinter 需要图像对象的任何地方使用。

tatras = ImageTk.PhotoImage(self.img)

我们创建照片图像。

label = Label(self, image=tatras)

将照片图像提供给标签窗口小部件的image参数。

label.image = tatras

为了不被垃圾收集,必须存储图像引用。

w, h = self.img.size
self.master.geometry(("%dx%d+300+300") % (w, h))

窗口的大小适合图像大小。

从 URL 读取图像

下一个示例从 URL 读取图像。

read_from_url.py

#!/usr/bin/python3

from PIL import Image
import requests
import sys

url = 'https://i.ytimg.com/vi/vEYsdh6uiS4/maxresdefault.jpg'

try:
    resp = requests.get(url, stream=True).raw

except requests.exceptions.RequestException as e:  
    sys.exit(1)

try:
    img = Image.open(resp)

except IOError:
    print("Unable to open image")
    sys.exit(1)

img.save('sid.jpg', 'jpeg')    

该示例从 URL 读取图像并将其保存在磁盘上。

import requests

我们使用requests库下载图像。

resp = requests.get(url, stream=True).raw

我们将图像读取为原始数据。

img = Image.open(resp)

Image是从响应对象创建的。

img.save('sid.jpg', 'jpeg')

图像被保存。

Pillow 绘制图像

Pillow 具有一些基本的 2D 图形功能。 ImageDraw模块为Image对象提供简单的 2D 图形。 我们可以创建新图像,注释或修饰现有图像,以及即时生成图形以供 Web 使用。

draw2image.py

#!/usr/bin/python3

from PIL import Image, ImageDraw

img = Image.new('RGBA', (200, 200), 'white')    
idraw = ImageDraw.Draw(img)

idraw.rectangle((10, 10, 100, 100), fill='blue')

img.save('rectangle.png')

该示例创建一个新图像,并在图像上绘制一个蓝色矩形。

img = Image.new('RGBA', (200, 200), 'white') 

创建一个新的Image。 图像模式为"RGBA"。 大小为200x200,背景为白色。

idraw = ImageDraw.Draw(img)

根据图像,我们创建ImageDraw对象。 现在我们可以在图像上执行一些绘制操作。

idraw.rectangle((10, 10, 100, 100), fill='blue')

使用rectangle()方法,我们在图像上绘制了一个蓝色矩形。

用 Pillow 创建水印

以下示例创建一个水印。

watermark.py

#!/usr/bin/python3

from PIL import Image, ImageDraw, ImageFont
import sys

try:
    tatras = Image.open("tatras.jpg")

except:
    print("Unable to load image")
    sys.exit(1)

idraw = ImageDraw.Draw(tatras)
text = "High Tatras"

font = ImageFont.truetype("arial.ttf", size=18)

idraw.text((10, 10), text, font=font)

tatras.save('tatras_watermarked.png')

我们使用ImageDraw模块创建水印。

font = ImageFont.truetype("arial.ttf", size=18)

我们创建 18 大小的 Arial 字体。

idraw.text((10, 10), text, font=font)

水印是通过text()方法创建的。 文本的默认颜色是白色。 我们使用创建的字体。

High Tatras

图:High Tatras

在本教程中,我们使用了 Python Pillow 库。

您可能也对以下相关教程感兴趣: Tkinter 教程Matplotlib 教程Python Arrow 教程PyQt5 教程和[ Python 教程

Python FTP 教程

原文: http://zetcode.com/python/ftp/

Python FTP 编程教程展示了如何使用ftplib库在 Python 中使用 FTP。 我们将连接到 FTP 服务器,列出目录,下载和上传文件。

FTP

文件传输协议(FTP)是用于在计算机网络上的客户端和服务器之间传输计算机文件的标准网络协议。 客户端和服务器使用一组 FTP 命令进行通信,例如 DELE,RETR 或 CWD。

许多服务器为 FTP 服务提供匿名 FTP 访问。 例如,有些 Linux 托管站点提供了一个匿名 FTP 帐户来下载分发映像。

Python ftplib

Python ftplib是实现 FTP 协议客户端的模块。 它包含一个 FTP 客户端类和一些帮助程序功能。

Python FTP

ftplib.FTP()创建 FTP 类的新实例。 给定主机后,将使用connect()方法建立与主机的连接。

上下文管理器

与 Python 3 不同,Python 2 没有使用 FTP 类实现的上下文管理器。 因此,在处理连接对象时,Python 2 代码需要稍微不同的方法。

import ftplib 

with ftplib.FTP('ftp.debian.org') as ftp:

with命令将自动关闭与 Python 3 代码的服务器连接。

import ftplib 
from contextlib import closing

with closing(ftplib.FTP('ftp.zetcode.com')) as ftp:

对于 Python 2 代码,我们需要使用contextlib模块的closing方法。

欢迎消息

getwelcome()返回服务器为响应初始连接而发送的欢迎消息。 该消息可能包含一些对用户有用的信息。

welcome.py

#!/usr/bin/python3

import ftplib

with ftplib.FTP('ftp.debian.org') as ftp:
    print(ftp.getwelcome())

该示例创建与 Debian FTP 服务器的连接,该服务器具有一个匿名帐户并返回其欢迎消息。

$ ./welcome.py 
220 ftp.debian.org FTP server

这是程序的输出。

目录列表

dir()方法产生一个目录列表。

listing.py

#!/usr/bin/python3

import ftplib

with ftplib.FTP('ftp.debian.org') as ftp:

    try:
        ftp.login()  

        files = []

        ftp.dir(files.append)

        print(files)

    except ftplib.all_errors as e:
        print('FTP error:', e)

该示例连接到ftp.debian.org主机,并检索初始登录目录的目录列表。

try:
    ftp.login()  

login()方法没有参数时; 我们连接到 FTP 站点的匿名帐户。

files = []

ftp.dir(files.append)

dir()方法产生目录列表,并将数据添加到列表中。

$ ./listing.py 
['drwxr-xr-x    9 1176     1176         4096 Sep 26 15:07 debian']

这是输出。

FTP 命令

FTP 客户端将命令发送到 FTP 服务器,例如PWDRETRftplib包含几种包装这些命令的方法。 使用sendcmd()voidcmd()方法发送命令。

ftp_commands.py

#!/usr/bin/python3

import ftplib 

with ftplib.FTP('ftp.debian.org') as ftp:

    try:
        ftp.login()  

        wdir = ftp.sendcmd('PWD')
        print(ftplib.parse257(wdir))

        wdir2 = ftp.pwd()
        print(wdir2)

    except ftplib.all_errors as e:
        print('FTP error:', e) 

该示例通过直接发送PWD命令并使用pwd()方法来检索当前工作目录。

wdir = ftp.sendcmd('PWD')

我们使用sendcmd()方法发送PWD命令。

print(ftplib.parse257(wdir))

parse257()是一个帮助程序方法,它从返回的字符串中检索目录,该字符串还包含状态代码。

wdir2 = ftp.pwd()
print(wdir2)

在这里,我们使用pwd()方法检索当前工作目录。

$ ./ftp_commands.py 
/
/

这是输出。

变更目录

cwd()方法更改当前工作目录。

change_directory.py

#!/usr/bin/python3

import ftplib

with ftplib.FTP('ftp.debian.org') as ftp:

    try:
        ftp.login()  

        wdir = ftp.pwd()
        print(wdir)

        ftp.cwd('debian')

        wdir2 = ftp.pwd()
        print(wdir2)

    except ftplib.all_errors as e:
        print('FTP error:', e) 

该示例使用cmd()方法更改为debian文件夹。

$ ./change_directory.py 
/
/debian

这是输出。

创建目录

使用mkd()方法创建目录。 此操作需要具有足够特权的用户帐户; 它不适用于匿名帐户。

create_directory.py

#!/usr/bin/python3

import ftplib 
from contextlib import closing

with closing(ftplib.FTP('ftp.example.com')) as ftp:

    try:
        ftp.login('user7', 's$cret')  

        ftp.mkd('newdir') 

        files = []

        ftp.retrlines('LIST', files.append)

        for fl in files:
            print(fl)

    except ftplib.all_errors as e:
        print('FTP error:', e)   

该示例连接到 FTP 服务器,并在登录文件夹中创建一个新目录。

ftp.login('user7', 's$cret')  

我们使用login()方法登录。

ftp.mkd('newdir') 

使用mkd()方法创建一个新目录。

files = []

ftp.retrlines('LIST', files.append)

使用LIST FTP 命令,我们检索文件列表和有关这些文件的信息。 该列表存储在files列表中。

$ ./create_directory.py 
drwx------   6 zetcode.com 117992          7 Sep 27 14:58 .
drwx------   6 zetcode.com 117992          7 Sep 27 14:58 ..
-rw-------   1 zetcode.com 117992        151 Jul 31  2015 .htaccess
drwxr-xr-x   2 0        0            4096 Sep 27 01:16 logs
drwx---r-x   2 zetcode.com 117992          2 Sep 27 14:58 newdir
drwx------   3 zetcode.com 117992          3 Mar 11  2011 sub
drwx------  26 zetcode.com 117992         31 Sep 25 15:32 web

从输出中我们可以看到newdir已创建。

获取文本文件的大小

SIZE命令及其等效的size()方法是确定文件大小的非标准方法。 尽管没有标准化,但是它由许多服务器实现。

text_file_size.py

#!/usr/bin/python3

import ftplib 

with ftplib.FTP('ftp.debian.org') as ftp:

    try:
        ftp.login()  

        size = ftp.size('debian/README')
        print(size)

    except ftplib.all_errors as e:
        print('FTP error:', e) 

该示例使用size()方法检索README文件的大小。

获取二进制文件的大小

要确定二进制文件的大小,我们必须切换到二进制模式。

binary_file_size.py

#!/usr/bin/python3

import ftplib 

with ftplib.FTP('ftp.debian.org') as ftp:

    try:
        ftp.login()  

        # TYPE A for ASCII mode
        ftp.sendcmd('TYPE I') 

        size = ftp.size('debian/ls-lR.gz')
        print(size)

    except ftplib.all_errors as e:
        print('FTP error:', e) 

该示例确定二进制文件的大小。

ftp.sendcmd('TYPE I') 

我们使用TYPE I命令进入二进制模式。

size = ftp.size('debian/ls-lR.gz')

我们得到一个二进制文件的大小。

下载文本文件

要下载文本文件,我们使用RETR FTP 命令。

download_text_file.py

#!/usr/bin/python3

import ftplib 
import os

with ftplib.FTP('ftp.debian.org') as ftp:

    file_orig = '/debian/README'
    file_copy = 'README'

    try:
        ftp.login()  

        with open(file_copy, 'w') as fp:

            res = ftp.retrlines('RETR ' + file_orig, fp.write)

            if not res.startswith('226 Transfer complete'):

                print('Download failed')
                if os.path.isfile(file_copy):
                    os.remove(file_copy)          

    except ftplib.all_errors as e:
        print('FTP error:', e) 

        if os.path.isfile(file_copy):
            os.remove(file_copy)

该示例从ftp.debian.org服务器下载文本文件。

with open(file_copy, 'w') as fp:

    res = ftp.retrlines('RETR ' + file_orig, fp.write)

我们获取文件并写入本地副本文件。

if not res.startswith('226 Transfer complete'):

    print('Download failed')
    if os.path.isfile(file_copy):
        os.remove(file_copy)  

如果下载失败,我们会打印一条错误消息并删除本地文件。

上传文本文件

具有storlines()方法的STOR命令用于上传文本文件。

upload_text_file.py

#!/usr/bin/python3

import ftplib 

with ftplib.FTP('ftp.example.com') as ftp:

    filename = 'README'

    try:    
        ftp.login('user7', 's$cret')  

        with open(filename, 'rb') as fp:

            res = ftp.storlines("STOR " + filename, fp)

            if not res.startswith('226 Transfer complete'):

                print('Upload failed')

    except ftplib.all_errors as e:
        print('FTP error:', e) 

在此示例中,我们将文本文件上传到 FTP 服务器。

在本教程中,我们使用了 Python ftplib

您可能也对以下相关教程感兴趣: Python 教程Python 集教程Python lambda 函数Python 列表推导Python 映射教程OpenPyXL 教程Python Requests 教程Python CSV 教程

Python 数据类型

原文: http://zetcode.com/lang/python/datatypes/

在 Python 编程教程的这一部分中,我们讨论 Python 数据类型。

电子表格,文本编辑器,计算器或聊天客户端等计算机程序可处理数据。 用于各种数据类型的工具是现代计算机语言的基本组成部分。

Python 数据类型定义

数据类型是一组值以及对这些值的允许操作。

Python 有很多有用的数据类型。 Python 的数据类型构建在语言的核心中。 它们易于使用和直接。

Python 布尔值

我们的世界建立了双重性。 有天与地,水与火,阴与阳,男人与女人,爱与恨。 在 Python 编程语言中,布尔数据类型是具有以下两个值之一的原始数据类型:TrueFalse。 这是基本的数据类型。 有趣的是,这种数据类型从一开始就不存在,但是后来才创建。

快乐的父母正在等待孩子的出生。 他们为两种可能性都选择了名称。 如果要成为男孩,他们可能选择了约翰。 如果要成为女孩,他们可能选择了维多利亚。

kid.py

#!/usr/bin/env python

# kid.py

import random

male = False
male = bool(random.randint(0, 1))

if male:
   print("We will use name John")
else:
   print("We will use name Victoria")

该脚本使用随机整数生成器来模拟我们的情况。

import random

在这里,我们导入用于计算随机数的随机模块。

male = bool(random.randint(0, 1))

在这里,我们使用两个函数。 randint()函数从给定的整数边界返回一个随机数。 在我们的情况下为 0 或 1。bool()函数将整数转换为布尔值。

if male:
    print("We will use name John")
else:
    print("We will use name Victoria")

我们打印名称。 if关键字适用于布尔值。 如果maleTrue,则在控制台上打印"We will use name John"。 如果它具有False值,我们将打印另一个字符串。

以下脚本显示了一些常见的值,它们被认为是TrueFalse

bool_fun.py

#!/usr/bin/env python

# bool_fun.py

print(bool(True))
print(bool(False))
print(bool("text"))
print(bool(""))
print(bool(' '))
print(bool(0))
print(bool())
print(bool(3))
print(bool(None))

该示例打印九个布尔值。

$ ./bool_fun.py 
True
False
True
False
True
False
False
True
False

这是bool_fun.py脚本的输出。

Python None

还有另一种特殊的数据类型-None。 此数据类型表示不存在,未知或为空。

none.py

#!/usr/bin/env python

# none.py

def function():
    pass

print(function())

在我们的示例中,我们定义一个函数。 功能将在本教程的后面部分介绍。 该功能不执行任何操作。 它不会显式返回任何值。 这样的函数将隐式返回None

$ ./none.py 
None

这是none.py脚本的输出。

Python 数字

在 Python 编程语言中,我们有整数,浮点数和复数。

如果我们使用整数,那么我们将处理离散实体。 我们将使用整数来计算苹果。

apples.py

#!/usr/bin/env python

# apples.py

# number of baskets
baskets = 16

# number of apples in a basket
apples_in_basket = 24

# we get the total number of apples
total = baskets * apples_in_basket

print("There are total of", total, "apples")

在脚本中,我们计算了苹果的总量。 我们使用乘法运算。

$ ./apples.py 
There are total of 384 apples

这是脚本的输出。

浮点数表示计算中的实数。 实数测量连续量。 假设一个短跑运动员跑了 1 个小时,跑了 9.87 秒。 他的公里/小时速度是多少?

sprinter.py

#!/usr/bin/env python

# sprinter.py

# 100 m is 0.1 km

distance = 0.1

# 9.87 s is 9.87/60*60 h

time = 9.87 / 3600

speed = distance / time

print("The average speed of a sprinter is {0} km/h".format(speed))

为了获得速度,我们将距离除以时间。

print("The average speed of a sprinter is {0} km/h".format(speed))

我们使用format()函数构建消息并将其打印到控制台。

$ ./sprinter.py 
The average speed of a sprinter is  36.4741641337 km/h

这是sprinter.py脚本的输出。 值 36.4741641337 是浮点数。

Python 字符串

字符串是代表计算机程序中文本数据的数据类型。

可以使用单引号,双引号和三引号在 Python 中创建字符串。 当我们使用三引号时,字符串可以跨越多行而无需使用转义符。

strings.py

#!/usr/bin/env python

# strings.py

a = "proximity alert"
b = 'evacuation'
c = """
requiem 
for
a 
tower
"""

print(a)
print(b)
print(c)

在我们的示例中,我们为abc变量分配了三个字符串字面值。 然后我们将它们打印到控制台。

$ ./strings.py 
proximity alert
evacuation

requiem 
for 
a 
tower

这是strings.py脚本的输出。

在处理字符串时,可以使用转义序列。 转义序列是在字符串中使用时具有特定用途的特殊字符。

print("   bbb\raaa") # prints aaabbb

回车\r是行尾到行首的控制字符。

strophe.py

#!/usr/bin/env python

# strophe.py

print("Incompatible, it don't matter though\n'cos someone's bound to hear my cry")
print("Speak out if you do\nYou're not easy to find")

新行是一个控制字符,它开始新的一行文本。

$ ./strophe.py 
Incompatible, it don't matter though
'cos someone's bound to hear my cry
Speak out if you do
You're not easy to find

接下来,我们检查退格控制字符。

print("Python\b\b\booo") # prints Pytooo

退格控制字符\b将光标向后移动一个字符。 在本例中,我们使用三个退格字符删除三个字母,并用三个o字符替换它们。

print("Towering\tinferno") # prints Towering        inferno

水平选项卡在文本之间放置一个空格。

"Johnie's dog"
'Johnie\'s dog'

单引号和双引号可以嵌套。 或者,如果仅使用单引号,则可以使用反斜杠来转义单引号的默认含义。

print("eagle has", len("eagle"), "characters")

我们可以使用len()函数来计算字符串的长度(以字符为单位)。

如果在字符串后附加r,则会得到原始字符串。 转义序列不被解释。

raw.py

#!/usr/bin/env python

# raw.py

print(r"Another world\n")

$ ./raw.py 
Another world\n

我们得到的字符串包括换行符。

在下一个示例中,我们显示了字符串乘法和连接。

strings2.py

#!/usr/bin/python

# strings2.py

print("eagle " * 5)

print("eagle " "falcon")

print("eagle " + "and " + "falcon")

*运算符将字符串重复 n 次。 在我们的情况下是五次。 彼此相邻的两个字符串字面值会自动连接在一起。 我们还可以使用+运算符显式连接字符串。

$ ./strings2.py 
eagle eagle eagle eagle eagle 
eagle falcon
eagle and falcon

这是strings.py脚本的输出。

Python 具有几种用于处理值集合的内置数据类型:元组,列表,集合和字典。

Python 元组

元组是不可变序列数据类型。 元组可以包含混合数据类型。

fruits = ("oranges", "apples", "bananas")

使用圆括号创建元组。 在这里,我们有一个由三种水果类型组成的元组。

fruits = "apples", "oranges", "bananas"
print(fruits)  # prints  ('apples', 'oranges', 'bananas')

括号不是必须的。 我们可以省略它们。

tuples.py

#!/usr/bin/env python

# tuples.py

first = (1, 2, 3)
second = (4, 5, 6)

print("len(first) : ", len(first))
print("max(first) : ", max(first))
print("min(first) : ", min(first))
print("first + second :", first + second)
print("first * 3 : ", first * 3)
print("1 in first : ", 1 in first)
print("5 not in second : ", 5 not in second)

此示例显示了元组的几个基本操作。 len()函数返回第一个元组中的元素数。 max()函数返回最大值,min()最小值。 加法运算符将两个元组相加,乘法运算符将元组相乘。 in运算符确定该值是否在元组中。

$ ./tuples.py
len(first) :  3
max(first) :  3
min(first) :  1
first + second : (1, 2, 3, 4, 5, 6)
first * 3 :  (1, 2, 3, 1, 2, 3, 1, 2, 3)
1 in first :  True
5 not in second :  False

这是脚本的输出。

接下来,我们将进行一些索引编制。

tuples2.py

#!/usr/bin/env python

# tuples2.py

five = (1, 2, 3, 4, 5)

print("five[0] : ", five[0])
print("five[-1] : ", five[-1])
print("five[-2] : ", five[-2])
print("five[:] : ", five[:])
print("five[0:4] : ", five[0:4])
print("five[1:2] : ", five[1:2])
print("five[:2] : ", five[:2])
print("five[:-1] : ", five[:-1])
print("five[:9] : ", five[:9])

为了从元组中获取值,我们使用方括号[]。 请注意,我们从 0 开始计算索引。如果一个元组中有五个对象,则索引为0...4。 如果使用负索引,则从元组的末尾获得一个值。 因此,索引-1 获得最后一个元素,-2 获得最后一个但只有一个元素。 Python 支持从元组创建切片。 为此,我们使用:分隔符。 例如,[0:4]给出(1, 2, 3, 4)。 请注意,不包括最后一个元素。

我们可以省略切片中的一个或两个索引。 [:4]给出(1, 2, 3, 4)。 它来自第一个元素。 [0:]给出(1,2,3,4,5)。 这次,包含了最后一个元素。 如果超出范围,我们只需将所有元素都包含在元组中。

$ ./tuples2.py 
five[0] :  1
five[-1] :  5
five[-2] :  4
five[:] :  (1, 2, 3, 4, 5)
five[0:4] :  (1, 2, 3, 4)
five[1:2] :  (2,)
five[:2] :  (1, 2)
five[:-1] :  (1, 2, 3, 4)
five[:9] :  (1, 2, 3, 4, 5)

这是输出。

元组可以包含几种混合数据类型。

tuples_mix.py

#!/usr/bin/env python

# tuples_mix.py

mix = (1, 2, "solaris", (1, 2, 3))

print("mix[1] :", mix[1])
print("mix[2] :", mix[2])
print("mix[3] :", mix[3])
print("mix[3][0] :", mix[3][0])
print("mix[3][1] :", mix[3][1])
print("mix[3][2] :", mix[3][2])

在我们的示例中,我们将数字,字符串和元组放入了混合元组中。

$ ./tuples_mix.py 
mix[1] : 2
mix[2] : solaris
mix[3] : (1, 2, 3)
mix[3][0] : 1
mix[3][1] : 2
mix[3][2] : 3

为了从嵌套元组中获取元素,我们使用了两个方括号。

当我们处理包含一个元素的元组时,会有一个例外。 括号也用在表达式中。 我们如何区分一个表达式和一个元素元组? Python 编程语言的创建者决定使用逗号来表示我们正在使用元组。

tuple_one.py

#!/usr/bin/env python

# tuple_one.py

print((3 + 7))
print((3 + 7, ))

在第一种情况下,我们有and表达式。 我们将 10 号打印到控制台。 在第二种情况下,我们处理一个元组。 我们打印一个包含数字 10 的元组。

$ ./tuple_one.py 
10
(10,)

这是输出。

Python 列表

列表是可变序列数据类型。 它可以包含混合数据类型。 列表和元组具有许多共同的特征。 由于列表是可修改的数据类型,因此它具有一些其他操作。 一整章专门介绍 Python 列表。

actors = ["Jack Nicholson", "Antony Hopkins", "Adrien Brody"]

该列表是使用方括号[]创建的。

list_simple.py

#!/usr/bin/env python

# simple_list.py

num = [0, 2, 5, 4, 6, 7]

print(num[0])
print(num[2:])
print(len(num))
print(num + [8, 9])

如前所述,我们可以在列表上使用与元组相同的操作。

$ ./list_simple.py 
0
[5, 4, 6, 7]
6
[0, 2, 5, 4, 6, 7, 8, 9]

这是输出。

接下来,我们将对列表进行排序。

list_sorting.py

#!/usr/bin/env python

# list_sorting.py

numbers = [4, 3, 6, 1, 2, 0, 5]

print(numbers)
numbers.sort()
print(numbers)

在脚本中,我们有一个数字列表。 要对这些数字进行排序,我们使用内置的sort()函数。

$ ./list_sorting.py 
[4, 3, 6, 1, 2, 0, 5]
[0, 1, 2, 3, 4, 5, 6]

reverse()函数将以相反的顺序对列表的元素进行排序。

numbers.reverse()   #  [5, 4, 3, 2, 1, 0]

使用count()方法对列表中的元素进行计数。

list_counting_elements.py

#!/usr/bin/env python

# list_counting_elements.py

numbers = [0, 0, 2, 3, 3, 3, 3]

print("zero is here",  numbers.count(0), "times")
print("one is here",   numbers.count(1), "times") 
print("two is here",   numbers.count(2), "time") 
print("three is here", numbers.count(3), "times") 

该脚本对列表中出现的次数进行计数。

$ ./list_counting_elements.py 
zero is here 2 times
one is here 0 times
two is here 1 time
three is here 4 times

接下来,我们将处理从列表中插入和删除项目。

list_modify.py

#!/usr/bin/env python

# list_modify.py

names = []

names.append("Frank")
names.append("Alexis")
names.append("Erika")
names.append("Ludmila")

print(names)

names.insert(0, "Adriana")
print(names)

names.remove("Frank")
names.remove("Alexis")
del names[1]
print(names)

del names[0]
print(names)

在我们的示例中,我们首先创建一个空名称列表。 我们使用append()函数将新项目添加到列表中。 元素以连续方式附加。 insert()函数在给定位置插入新元素。 现有元素不会被删除,它们将被重定位。 remove()函数从列表中删除特定项目。 如果要基于索引删除项目,请使用del关键字。

$ ./list_modify.py 
['Frank', 'Alexis', 'Erika', 'Ludmila']
['Adriana', 'Frank', 'Alexis', 'Erika', 'Ludmila']
['Adriana', 'Ludmila']
['Ludmila']

这是list_modify.py脚本的输出。

以下程序提供了另外两个功能。

list_modify2.py

#!/usr/bin/env python

# list_modify2.py

first = [1, 2, 3]
second = [4, 5, 6]

first.extend(second)
print(first)

first[0] = 11
first[1] = 22
first[2] = 33
print(first)

print(first.pop(5))
print(first)

extend()方法将整个列表附加到另一个列表。 要修改列表中的元素,我们可以使用赋值运算符。 pop()方法从列表中获取一个项目并返回它。

$ ./list_modify2.py 
[1, 2, 3, 4, 5, 6]
[11, 22, 33, 4, 5, 6]
6
[11, 22, 33, 4, 5]

这是输出。

在下面的示例中,我们将找出元素的索引。

list_index.py

#!/usr/bin/env python

# list_index.py

numbers = [0, 1, 2, 3, 3, 4, 5]

print(numbers.index(1))
print(numbers.index(3))

要在列表中查找索引,我们使用index()方法。 如果有更多的元素出现,则该方法返回第一个元素的索引。

$ ./list_index.py 
1
3

这是list_index.py脚本的输出。

接下来,我们将进行一些转换。

list_transform.py

#!/usr/bin/env python

# list_transform.py

first = [1, 2, 3]
second = (4, 5, 6)

print(tuple(first))
print(list(second))

print(first)
print(second)

我们可以使用tuple()函数从列表中创建一个元组,并使用list()函数从元组中创建一个列表。 注意原始对象没有被修改; 函数仅返回那些转换后的集合。

$ ./list_transform.py 
(1, 2, 3)
[4, 5, 6]
[1, 2, 3]
(4, 5, 6)

Python 集

set是无重复数据的无序数据集合。 集合支持诸如并集,相交或求差的运算; 与数学相似。

sets.py

#!/usr/bin/env python

set1 = set(['a', 'b', 'c', 'c', 'd'])
set2 = set(['a', 'b', 'x', 'y', 'z'])

print("set1: " , set1)
print("set2: " , set2)
print("intersection: ", set1 & set2)
print("union: ", set1 | set2)
print("difference: ", set1 - set2)
print("symmetric difference: ", set1 ^ set2)

在我们的示例中,我们有两组。 我们使用set()函数创建集合。 相交操作返回都在set1set2中的元素。 联合操作返回两个集合中的所有元素。 差异返回set1中的元素,但不是set2的元素。 最后,对称差返回set1set2中的元素,但两者都不是。

$ ./sets.py 
set1: set(['a', 'c', 'b', 'd'])
set2: set(['a', 'x', 'b', 'y', 'z'])
intersection: set(['a', 'b'])
union: set(['a', 'c', 'b', 'd', 'y', 'x', 'z'])
difference: set(['c', 'd'])
symmetric difference: set(['c', 'd', 'y', 'x', 'z'])

这是sets.py脚本的输出。

接下来,我们介绍一些其他带有集合的操作。

set2.py

#!/usr/bin/env python

# sets2.py

set1 = set([1, 2])
set1.add(3)
set1.add(4)

set2 = set([1, 2, 3, 4, 6, 7, 8])
set2.remove(8)

print(set1)
print(set2)

print("Is set1 subset of set2 ? :", set1.issubset(set2))
print("Is set1 superset of set2 ? :", set1.issuperset(set2))

set1.clear()
print(set1)

add()方法将一个项目添加到集合中。 remove()项目从集中删除一个项目。 clear()方法从集合中删除所有项目。 如果set2中的每个元素也在set1中,则set1set2的超集。 如果set1中的每个元素也位于set2中,则set1set2的子集。

$ ./sets2.py 
set([1, 2, 3, 4])
set([1, 2, 3, 4, 6, 7])
Is set1 subset of set2 ? :  True
Is set1 superset of set2 ? :  False
set([])

如果我们需要一个不可变的集合,可以使用frozenset()函数创建一个冻结集合。

fs = frozenset(['a', 'b', 'c'])

该行从列表中创建一个冻结集。

Python 字典

Python 字典是一组键值对。 字典中的元素由键索引。 字典中的键必须唯一。 由于字典数据类型的重要性,本 Python 教程中有整整一章介绍了字典。

dictionary_simple.py

#!/usr/bin/env python

# dictionary_simple.py

words = { 'girl': 'Maedchen', 'house': 'Haus', 'death': 'Tod' }

print(words['house'])

print(words.keys())
print(words.values())
print(words.items())

print(words.pop('girl'))
print(words)

words.clear()
print(words)

我们的第一个示例显示了字典数据类型的一些基本用法。 我们打印特定的值,字典的键和值。 items()方法返回一个字典(键,值)对的列表作为元组。

$ ./dictionary_simple.py 
Haus
['house', 'girl', 'death']
['Haus', 'Maedchen', 'Tod']
[('house', 'Haus'), ('girl', 'Maedchen'), ('death', 'Tod')]
Maedchen
{'house': 'Haus', 'death': 'Tod'}
{}

在 Python 教程的这一部分中,我们描述了 Python 数据类型。

Python Requests 教程

原文: http://zetcode.com/python/requests/

在本教程中,我们展示了如何使用 Python Requests 模块。 我们获取数据,发布数据,流数据并连接到安全的网页。 在示例中,我们使用在线服务,nginx 服务器,Python HTTP 服务器和 Flask 应用。

ZetCode 也有一个简洁的 Python 教程

超文本传输​​协议(HTTP)是用于分布式协作超媒体信息系统的应用协议。 HTTP 是万维网数据通信的基础。

Python Requests

Requests 是一个简单优雅的 Python HTTP 库。 它提供了通过 HTTP 访问 Web 资源的方法。 Requests 是内置的 Python 模块。

$ sudo service nginx start

我们在本地主机上运行 nginx Web 服务器。 我们的一些示例使用nginx服务器。

Python Requests 版本

第一个程序打印请求库的版本。

version.py

#!/usr/bin/env python3

import requests

print(requests.__version__)
print(requests.__copyright__)

该程序将打印请求的版本和版权。

$ ./version.py
2.21.0
Copyright 2018 Kenneth Reitz

这是示例的示例输出。

Python Requests 读取网页

get()方法发出 GET 请求; 它获取由给定 URL 标识的文档。

read_webpage.py

#!/usr/bin/env python3

import requests as req

resp = req.get("http://www.webcode.me")

print(resp.text)

该脚本获取www.webcode.me网页的内容。

resp = req.get("http://www.webcode.me")

get()方法返回一个响应对象。

print(resp.text)

text属性包含响应的内容,以 Unicode 表示。

$ ./read_webpage.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My html page</title>
</head>
<body>

    <p>
        Today is a beautiful day. We go swimming and fishing.
    </p>

    <p>
         Hello there. How are you?
    </p>

</body>
</html>

这是read_webpage.py脚本的输出。

以下程序获取一个小型网页,并剥离其 HTML 标签。

strip_tags.py

#!/usr/bin/env python3

import requests as req
import re

resp = req.get("http://www.webcode.me")

content = resp.text

stripped = re.sub('<[^<]+?>', '', content)
print(stripped)

该脚本会剥离www.webcode.me网页的 HTML 标签。

stripped = re.sub('<[^<]+?>', '', content)

一个简单的正则表达式用于剥离 HTML 标记。

HTTP 请求

HTTP 请求是从客户端发送到浏览器的消息,以检索某些信息或采取某些措施。

Requestrequest方法创建一个新请求。 请注意,request模块具有一些更高级的方法,例如get()post()put(),为我们节省了一些输入。

create_request.py

#!/usr/bin/env python3

import requests as req

resp = req.request(method='GET', url="http://www.webcode.me")
print(resp.text)

该示例创建一个 GET 请求并将其发送到http://www.webcode.me

Python Requests 获取状态

Response对象包含服务器对 HTTP 请求的响应。 其status_code属性返回响应的 HTTP 状态代码,例如 200 或 404。

get_status.py

#!/usr/bin/env python3

import requests as req

resp = req.get("http://www.webcode.me")
print(resp.status_code)

resp = req.get("http://www.webcode.me/news")
print(resp.status_code)

我们使用get()方法执行两个 HTTP 请求,并检查返回的状态。

$ ./get_status.py
200
404

200 是成功 HTTP 请求的标准响应,而 404 则表明找不到所请求的资源。

Python Requests HEAD 方法

head()方法检索文档标题。 标头由字段组成,包括日期,服务器,内容类型或上次修改时间。

head_request.py

#!/usr/bin/env python3

import requests as req

resp = req.head("http://www.webcode.me")

print("Server: " + resp.headers['server'])
print("Last modified: " + resp.headers['last-modified'])
print("Content type: " + resp.headers['content-type'])

该示例打印服务器,www.webcode.me网页的上次修改时间和内容类型。

$ ./head_request.py
Server: nginx/1.6.2
Last modified: Sat, 20 Jul 2019 11:49:25 GMT
Content type: text/html

这是head_request.py程序的输出。

Python Requests GET 方法

get()方法向服务器发出 GET 请求。 GET 方法请求指定资源的表示形式。

httpbin.org是免费提供的 HTTP 请求&响应服务。

mget.py

#!/usr/bin/env python3

import requests as req

resp = req.get("https://httpbin.org/get?name=Peter")
print(resp.text)

该脚本将具有值的变量发送到httpbin.org服务器。 该变量直接在 URL 中指定。

$ ./mget.py
{
  "args": {
    "name": "Peter"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.21.0"
  },
  ...
}

这是示例的输出。

mget2.py

#!/usr/bin/env python3

import requests as req

payload = {'name': 'Peter', 'age': 23}
resp = req.get("https://httpbin.org/get", params=payload)

print(resp.url)
print(resp.text)

get()方法采用params参数,我们可以在其中指定查询参数。

payload = {'name': 'Peter', 'age': 23}

数据在 Python 字典中发送。

resp = req.get("https://httpbin.org/get", params=payload)

我们将 GET 请求发送到httpbin.org站点,并传递params参数中指定的数据。

print(resp.url)
print(resp.text)

我们将 URL 和响应内容打印到控制台。

$ ./mget2.py
http://httpbin.org/get?name=Peter&age=23
{
  "args": {
    "age": "23",
    "name": "Peter"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.21.0"
  },
  ...
}

这是示例的输出。

Python Requests 重定向

重定向是将一个 URL 转发到另一个 URL 的过程。 HTTP 响应状态代码 301“永久移动”用于永久 URL 重定向; 302 找到临时重定向。

redirect.py

#!/usr/bin/env python3

import requests as req

resp = req.get("https://httpbin.org/redirect-to?url=/")

print(resp.status_code)
print(resp.history)
print(resp.url)

在示例中,我们向https://httpbin.org/redirect-to页面发出 GET 请求。 该页面重定向到另一个页面; 重定向响应存储在响应的history属性中。

$ ./redirect.py
200
[<Response [302]>]
https://httpbin.org/

https://httpbin.org/redirect-to的 GET 请求被重定向到https://httpbin.org 302。

在第二个示例中,我们不遵循重定向。

redirect2.py

#!/usr/bin/env python3

import requests as req

resp = req.get("https://httpbin.org/redirect-to?url=/", allow_redirects=False)

print(resp.status_code)
print(resp.url)

allow_redirects参数指定是否遵循重定向。 默认情况下,重定向之后。

$ ./redirect2.py
302
https://httpbin.org/redirect-to?url=/

这是示例的输出。

用 nginx 重定向

在下一个示例中,我们显示如何在 nginx 服务器中设置页面重定向。

location = /oldpage.html {

        return 301 /newpage.html;
}

将这些行添加到位于 Debian 上/etc/nginx/sites-available/default的 Nginx 配置文件中。

$ sudo service nginx restart

编辑完文件后,我们必须重新启动 nginx 才能应用更改。

oldpage.html

<!DOCTYPE html>
<html>
<head>
<title>Old page</title>
</head>
<body>
<p>
This is old page
</p>
</body>
</html>

这是位于 nginx 文档根目录中的oldpage.html文件。

newpage.html

<!DOCTYPE html>
<html>
<head>
<title>New page</title>
</head>
<body>
<p>
This is a new page
</p>
</body>
</html>

这是newpage.html

redirect3.py

#!/usr/bin/env python3

import requests as req

resp = req.get("http://localhost/oldpage.html")

print(resp.status_code)
print(resp.history)
print(resp.url)

print(resp.text)

该脚本访问旧页面并遵循重定向。 如前所述,默认情况下,请求遵循重定向。

$ ./redirect3.py
200
(<Response [301]>,)
http://localhost/files/newpage.html
<!DOCTYPE html>
<html>
<head>
<title>New page</title>
</head>
<body>
<p>
This is a new page
</p>
</body>
</html>

这是示例的输出。

$ sudo tail -2 /var/log/nginx/access.log
127.0.0.1 - - [21/Jul/2019:07:41:27 -0400] "GET /oldpage.html HTTP/1.1" 301 184
"-" "python-requests/2.4.3 CPython/3.4.2 Linux/3.16.0-4-amd64"
127.0.0.1 - - [21/Jul/2019:07:41:27 -0400] "GET /newpage.html HTTP/1.1" 200 109
"-" "python-requests/2.4.3 CPython/3.4.2 Linux/3.16.0-4-amd64"

access.log文件中可以看到,该请求已重定向到新的文件名。 通信包含两个 GET 请求。

用户代理

在本节中,我们指定用户代理的名称。 我们创建自己的 Python HTTP 服务器。

http_server.py

#!/usr/bin/env python3

from http.server import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):

        message = "Hello there"

        self.send_response(200)

        if self.path == '/agent':

            message = self.headers['user-agent']

        self.send_header('Content-type', 'text/html')
        self.end_headers()

        self.wfile.write(bytes(message, "utf8"))

        return

def main():

    print('starting server on port 8081...')

    server_address = ('127.0.0.1', 8081)
    httpd = HTTPServer(server_address, MyHandler)
    httpd.serve_forever()

main()

我们有一个简单的 Python HTTP 服务器。

if self.path == '/agent':

    message = self.headers['user-agent']

如果路径包含'/agent',则返回指定的用户代理。

user_agent.py

#!/usr/bin/env python3

import requests as req

headers = {'user-agent': 'Python script'}

resp = req.get("http://localhost:8081/agent", headers=headers)
print(resp.text)

该脚本向我们的 Python HTTP 服务器创建一个简单的 GET 请求。 要向请求添加 HTTP 标头,我们将字典传递给headers参数。

headers = {'user-agent': 'Python script'}

标头值放置在 Python 字典中。

resp = req.get("http://localhost:8081/agent", headers=headers)

这些值将传递到headers参数。

$ simple_server.py
starting server on port 8081...

首先,我们启动服务器。

$ ./user_agent.py
Python script

然后我们运行脚本。 服务器使用我们随请求发送的代理名称进行了响应。

Python Requests POST 值

post方法在给定的 URL 上调度 POST 请求,为填写的表单内容提供键/值对。

post_value.py

#!/usr/bin/env python3

import requests as req

data = {'name': 'Peter'}

resp = req.post("https://httpbin.org/post", data)
print(resp.text)

脚本使用具有Peter值的name键发送请求。 POST 请求通过post方法发出。

$ ./post_value.py
{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "name": "Peter"
  },
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Content-Length": "10",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "python-requests/2.21.0"
  },
  "json": null,
  ...
}

这是post_value.py脚本的输出。

Python Requests 上传图像

在以下示例中,我们将上传图片。 我们使用 Flask 创建一个 Web 应用。

app.py

#!/usr/bin/env python3

import os
from flask import Flask, request

app = Flask(__name__)

@app.route("/")
def home():
    return 'This is home page'

@app.route("/upload", methods=['POST'])
def handleFileUpload():

    msg = 'failed to upload image'

    if 'image' in request.files:

        photo = request.files['image']

        if photo.filename != '':

            photo.save(os.path.join('.', photo.filename))
            msg = 'image uploaded successfully'

    return msg

if __name__ == '__main__':
    app.run()

这是具有两个端点的简单应用。 /upload端点检查是否有某些图像并将其保存到当前目录。

upload_file.py

#!/usr/bin/env python3

import requests as req

url = 'http://localhost:5000/upload'

with open('sid.jpg', 'rb') as f:

    files = {'image': f}

    r = req.post(url, files=files)
    print(r.text)

我们将图像发送到 Flask 应用。 该文件在post()方法的files属性中指定。

JSON 格式

JSON (JavaScript 对象表示法)是一种轻量级的数据交换格式。 人类很容易读写,机器也很容易解析和生成。

JSON 数据是键/值对的集合; 在 Python 中,它是通过字典实现的。

读取 JSON

在第一个示例中,我们从 PHP 脚本读取 JSON 数据。

send_json.php

<?php

$data = [ 'name' => 'Jane', 'age' => 17 ];
header('Content-Type: application/json');

echo json_encode($data);

PHP 脚本发送 JSON 数据。 它使用json_encode()函数完成该工作。

read_json.py

#!/usr/bin/env python3

import requests as req

resp = req.get("http://localhost/send_json.php")
print(resp.json())

read_json.py读取 PHP 脚本发送的 JSON 数据。

print(resp.json())

json()方法返回响应的 json 编码内容(如果有)。

$ ./read_json.py
{'age': 17, 'name': 'Jane'}

这是示例的输出。

发送 JSON

接下来,我们将 JSON 数据从 Python 脚本发送到 PHP 脚本。

parse_json.php

<?php

$data = file_get_contents("php://input");

$json = json_decode($data , true);

foreach ($json as $key => $value) {

    if (!is_array($value)) {
        echo "The $key is $value\n";
    } else {
        foreach ($value as $key => $val) {
            echo "The $key is $value\n";
        }
    }
}

该 PHP 脚本读取 JSON 数据,并发送带有已解析值的消息。

send_json.py

#!/usr/bin/env python3

import requests as req

data = {'name': 'Jane', 'age': 17}

resp = req.post("http://localhost/parse_json.php", json=data)
print(resp.text)

该脚本将 JSON 数据发送到 PHP 应用并读取其响应。

data = {'name': 'Jane', 'age': 17}

这是要发送的数据。

resp = req.post("http://localhost/parse_json.php", json=data)

包含 JSON 数据的字典将传递给json参数。

$ ./send_json.py
The name is Jane
The age is 17

这是示例输出。

从字典中检索定义

在以下示例中,我们在 www.dictionary.com 上找到术语的定义。 要解析 HTML,我们使用lxml模块。

$ pip install lxml

我们使用pip工具安装lxml模块。

get_term.py

#!/usr/bin/env python3

import requests as req
from lxml import html
import textwrap

term = "dog"

resp = req.get("http://www.dictionary.com/browse/" + term)
root = html.fromstring(resp.content)

for sel in root.xpath("//span[contains(@class, 'one-click-content')]"):

    if sel.text:

        s = sel.text.strip()

        if (len(s) > 3):

            print(textwrap.fill(s, width=50))

在此脚本中,我们在www.dictionary.com上找到了术语狗的定义。 lxml模块用于解析 HTML 代码。

注意:包含定义的标签可能会在一夜之间发生变化。 在这种情况下,我们需要调整脚本。

from lxml import html

lxml模块可用于解析 HTML。

import textwrap

textwrap模块用于将文本包装到特定宽度。

resp = req.get("http://www.dictionary.com/browse/" + term)

为了执行搜索,我们在 URL 的末尾附加了该词。

root = html.fromstring(resp.content)

我们需要使用resp.content而不是resp.text,因为html.fromstring()隐式地希望字节作为输入。 (resp.content以字节为单位返回内容,而resp.text以 Unicode 文本形式返回。

for sel in root.xpath("//span[contains(@class, 'one-click-content')]"):

    if sel.text:

        s = sel.text.strip()

        if (len(s) > 3):

            print(textwrap.fill(s, width=50))

我们解析内容。 主要定义位于span标签内部,该标签具有one-click-content属性。 我们通过消除多余的空白和杂散字符来改善格式。 文字宽度最大为 50 个字符。 请注意,此类解析可能会更改。

$ ./get_term.py
a domesticated canid,
any carnivore of the dog family Canidae, having
prominent canine teeth and, in the wild state, a
long and slender muzzle, a deep-chested muscular
body, a bushy tail, and large, erect ears.
...

这是定义的部分列表。

Python Requests 流请求

流正在传输音频和/或视频数据的连续流,同时正在使用较早的部分。 Requests.iter_lines()遍历响应数据,一次一行。 在请求上设置stream=True可以避免立即将内容读取到内存中以获得较大响应。

streaming.py

#!/usr/bin/env python3

import requests as req

url = "https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf"

local_filename = url.split('/')[-1]

r = req.get(url, stream=True)

with open(local_filename, 'wb') as f:

    for chunk in r.iter_content(chunk_size=1024):

        f.write(chunk)

该示例流式传输 PDF 文件并将其写入磁盘。

r = req.get(url, stream=True)

在发出请求时将stream设置为True,除非我们消耗掉所有数据或调用Response.close(),否则请求无法释放回池的连接。

with open(local_filename, 'wb') as f:

    for chunk in r.iter_content(chunk_size=1024):

        f.write(chunk)

我们按 1 KB 的块读取资源,并将其写入本地文件。

Python Requests 凭证

auth参数提供基本的 HTTP 认证; 它使用一个元组的名称和密码来用于领域。 安全领域是一种用于保护 Web 应用资源的机制。

$ sudo apt-get install apache2-utils
$ sudo htpasswd -c /etc/nginx/.htpasswd user7
New password:
Re-type new password:
Adding password for user user7

我们使用htpasswd工具创建用于基本 HTTP 认证的用户名和密码。

location /secure {

        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/.htpasswd;
}

在 nginx /etc/nginx/sites-available/default配置文件中,我们创建一个安全页面。 领域的名称是"Restricted Area"

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<title>Secure page</title>
</head>

<body>

<p>
This is a secure page.
</p>

</body>

</html>

/usr/share/nginx/html/secure目录中,我们有这个 HTML 文件。

credentials.py

#!/usr/bin/env python3

import requests as req

user = 'user7'
passwd = '7user'

resp = req.get("http://localhost/secure/", auth=(user, passwd))
print(resp.text)

该脚本连接到安全网页; 它提供访问该页面所需的用户名和密码。

$ ./credentials.py
<!DOCTYPE html>
<html lang="en">
<head>
<title>Secure page</title>
</head>

<body>

<p>
This is a secure page.
</p>

</body>

</html>

使用正确的凭据,credentials.py脚本返回受保护的页面。

在本教程中,我们使用了 Python Requests 模块。 您可能对以下相关教程感兴趣: Python 列表推导式Python SimpleJson 教程Python FTP 教程OpenPyXL 教程,[ Python CSV 教程Python 教程

列出所有 Python 教程

Python Arrow 教程

原文: http://zetcode.com/python/arrow/

Python Arrow 教程显示了如何在带有箭头模块的 Python 中使用日期和时间。

Python Arrow

Arrow 是用于处理日期和时间的 Python 模块。 与内置的日期和时间工具相比,它使创建,操作,格式化和转换日期,时间和时间戳变得更加容易。

安装 Arrow

Arrow 模块使用以下命令安装:

$ sudo pip3 install arrow

我们使用pip3命令安装arrow模块。

UTC 时间

实际需要一个全球时间。 全球时间可以避免时区和夏令时的混淆。 UTC(世界标准时间)是主要时间标准。 UTC 用于航空,天气预报,飞行计划,空中交通管制通关和映射。 与当地时间不同,UTC 不会随季节变化而变化。

utc_time.py

#!/usr/bin/python3

import arrow

utc = arrow.utcnow()
print(utc)
print(utc.to('local'))

使用utcnow()函数创建 UTC 时间。

print(utc.to('local'))

使用to()方法,我们将 UTC 时间转换为本地时间。

当地时间

本地时间是特定区域或时区中的时间。

local_time.py

#!/usr/bin/python3

import arrow

now = arrow.now()
print(now)
print(now.to('UTC'))

使用now()函数创建本地时间。 to()方法用于将本地时间转换为 UTC 时间。

解析时间

get()方法用于解析时间。

parse_time.py

#!/usr/bin/python3

import arrow

d1 = arrow.get('2012-06-05 16:20:03', 'YYYY-MM-DD HH:mm:ss')
print(d1)

d2 = arrow.get(1504384602)
print(d2)

该示例从日期和时间字符串以及时间戳解析时间。

$ ./parse_time.py 
2012-06-05T16:20:03+00:00
2017-09-02T20:36:42+00:00

这是输出。

Unix 时间

Unix 时间是自 Unix 时代以来的秒数。 timestamp属性返回自 1970 年 1 月 1 日协调世界时以来 0 小时 0 分 0 秒以来以秒为单位的时间值。

unix_time.py

#!/usr/bin/python3

import arrow

utc = arrow.utcnow()
print(utc)

unix_time = utc.timestamp
print(unix_time)

date = arrow.Arrow.fromtimestamp(unix_time)
print(date)

该示例显示本地时间和 Unix 时间。 然后,它将 Unix 时间转换回date对象。

date = arrow.Arrow.fromtimestamp(unix_time)

使用fromtimestamp()方法,我们将 Unix 时间转换回箭头日期对象。

2017-09-02T21:57:11.483795+02:00
1504382231
2017-09-02T21:57:11+02:00

这是输出。

也可以将日期格式化为 Unix 时间。

format2unix.py

#!/usr/bin/python3

import arrow

utc = arrow.utcnow()

print(utc.format('X'))

通过将'X'说明符传递给format()方法,我们将当前本地日期打印为 Unix 时间。

$ ./format2unix.py 
1504383196

这是输出。

格式化日期和时间

日期和时间可以用format()方法格式化。

formatting.py

#!/usr/bin/python3

import arrow

now = arrow.now()

year = now.format('YYYY')
print("Year: {0}".format(year))

date = now.format('YYYY-MM-DD')
print("Date: {0}".format(date))

date_time = now.format('YYYY-MM-DD HH:mm:ss')
print("Date and time: {0}".format(date_time))

date_time_zone = now.format('YYYY-MM-DD HH:mm:ss ZZ')
print("Date and time and zone: {0}".format(date_time_zone))

该示例使用format()方法以各种格式显示本地日期和时间。

$ ./formatting.py 
Year: 2017
Date: 2017-09-02
Date and time: 2017-09-02 22:00:32
Date and time and zone: 2017-09-02 22:00:32 +02:00

这是输出。

转换为区域时间

使用to()方法,我们可以将日期和时间转换为区域时间。

converting.py

#!/usr/bin/python3

import arrow

utc = arrow.utcnow()

print(utc.to('US/Pacific').format('HH:mm:ss'))
print(utc.to('Europe/Bratislava').format('HH:mm:ss'))
print(utc.to('Europe/Moscow').format('HH:mm:ss'))

该示例创建一个 UTC 时间并将其转换为三个区域时间。

$ ./converting.py 
13:24:06
22:24:06
23:24:06

这是输出。

工作日

可以使用weekday()format()方法找到日期的工作日。

weekday.py

#!/usr/bin/python3

import arrow

d1 = arrow.get('1948-12-13')

print(d1.weekday())
print(d1.format('dddd'))

该代码示例的工作日为"1948-12-13"

$ ./weekday.py 
0
Monday

1948 年 12 月 12 日,是星期一。

移动时间

shift()方法用于移动时间。

shifting.py

#!/usr/bin/python3

import arrow

now = arrow.now()

print(now.shift(hours=5).time())
print(now.shift(days=5).date())

print(now.shift(years=-8).date())

该示例计算当前本地时间并将其偏移三倍。

print(now.shift(hours=5).time())

我们将时间提前了五个小时。

print(now.shift(days=5).date())

我们将日期提前五天。

print(now.shift(years=-8).date())

在这里,我们将日期向后移八年。

$ ./shifting.py 
03:44:23.100887
2017-09-07
2009-09-02

这是输出。

夏令时

夏令时(DST)是在夏季的几个月中增加时钟的一种做法,因此晚上的夏时制持续时间更长。 在春季开始时将时间向前调整一小时,在秋季将时间向后调整为标准时间。

daylightsaving.py.py

#!/usr/bin/python3

import arrow

now = arrow.now()

print(now.format("YYYY-MM-DD HH:mm:ss ZZ"))
print(now.dst())

该示例使用dst()显示夏令时。

$ ./daylightsaving.py 
2017-09-02 22:46:37 +02:00
1:00:00

输出显示本地时间已调整一小时。

人性化的日期和时间

在社交网站上,我们经常可以看到诸如“一个小时前”或“5 分钟前”之类的术语,这些术语可以为人们提供有关帖子创建或修改时间的快速信息。 Arrow 包含humanize()方法来创建此类术语。

humanize.py

#!/usr/bin/python3

import arrow

now = arrow.now()

d1 = now.shift(minutes=-15).humanize()
print(d1)

d2 = now.shift(hours=5).humanize()
print(d2)

该示例将两个日期人性化。

$ ./humanizing.py 
15 minutes ago
in 4 hours

这是输出。

在本教程中,我们使用带有箭头模块的 Python 中的日期和时间。

您可能也对以下相关教程感兴趣: Beautifulsoup 教程Python 教程Python 列表推导式OpenPyXL 教程,Python Requests 教程和 Python CSV 教程

Python 列表推导式

原文: http://zetcode.com/articles/pythonlistcomprehensions/

在本教程中,我们将学习使用 Python 列表推导。

Python 列表推导式

列表推导式是一种基于现有列表创建列表的语法结构。 列表推导式为创建列表提供了一种简洁的方法。 常见的要求是创建新列表,其中每个元素是应用于另一序列的每个成员或可迭代的某些操作的结果,或者创建满足特定条件的那些元素的子序列。

Python 列表推导式用法

列表推导可用于:

  • 转换列表
  • 过滤列表

列表推导式的语法受集合的数学符号的影响。 Python 语法受 Haskell 编程语言启发。

S = {x² : x in {0 ... 16}}

这是用于创建一组整数值的数学符号。

L = [expression for variable in sequence [if condition]]

上面的伪代码显示了列表推导式的语法。 它由三部分组成:for循环,可选条件和表达式。 for循环遍历整个序列。 对于每个循环,如果满足条件,则对表达式进行求值。 如果计算出该值,它将被添加到新列表中。 for循环和if条件可以有多个。

Python 列表推导式转换列表

下面的示例借助列表推导式将一个列表转换为另一个列表。

multiply_elements.py

#!/usr/bin/python3

a = [1, 2, 3, 4, 5, 6]

b = [e * 2 for e in a]
print(b)

在第一个示例中,我们通过将每个元素乘以 2 从现有列表中创建一个新列表。

b = [e * 2 for e in a]

a列表中的每个元素乘以 2,并将结果添加到新的b列表中。

$ ./multiply_elements.py 
[2, 4, 6, 8, 10, 12]

每个元素都乘以 2。

从摄氏计算华氏温度

我们有摄氏温度的列表。 我们要创建一个新的温度表,以华氏温度表示。

fahrenheit_celsius.py

#!/usr/bin/python3

celsius = [22, 28, 33, 42, 52]

fahr = [e * 9/5 + 32 for e in celsius]
print(fahr)

该示例创建了一个新的华氏温度列表,该列表是根据摄氏温度列表计算得出的。

fahr = [e * 9/5 + 32 for e in celsius]

计算是在 Python 列表推导的第三个表达式部分中完成的。

$ ./fahrenheit_celsius.py 
[71.6, 82.4, 91.4, 107.6, 125.6]

这是示例的输出。

Python 列表推导式过滤列表

在下面的示例中,我们将使用列表推导式来过滤列表。

filter_positive.py

#!/usr/bin/python3

a = [-4, 2, 0, -1, 12, -3]

b = [e for e in a if e > 0]
print(b)

我们有一个整数列表。 我们创建一个仅包含正整数的新列表。

b = [e for e in a if e > 0]

为了只包含正数,我们使用了if条件,该条件应用于每个元素。 仅当满足条件的元素才包含在新列表中。

$ ./filter_positive.py 
[2, 12]

这是示例的输出。

下一个示例按元素类型过滤元素。

filter_by_type.py

#!/usr/bin/python3

a = ['a', 2, 'c', 12, 3, 'd']

b = [e for e in a if type(e) == int]
c = [e for e in a if type(e) == str]

print(b)
print(c)

我们有一个元素列表,它们是整数和字符串。 我们创建两个新列表; 一个只有整数,只有一个字符串。

b = [e for e in a if type(e) == int]

在这里,我们创建一个列表b,它将仅包含整数值。 type()函数用于确定元素的类型。

$ ./filter_by_type.py 
[2, 12, 3]
['a', 'c', 'd']

这是示例的输出。

Python 列表推导式多个if条件

Python 列表推导中的条件可以使用多个。

multiple_conditions.py

#!/usr/bin/python3

a = [9, 2, 18, 14, 22, 11, 7, 19, 23]

b = [e for e in a if e > 10 if e < 20]
print(b)

我们从列表a创建一个新的整数列表,它们大于 10 且小于 20。

b = [e for e in a if e > 10 if e < 20]

在此列表推导式中,我们使用两个if条件。

$ ./multiple_conditions.py 
[18, 14, 11, 19]

这是示例的输出。

Python 列表推导式多个for循环

Python 列表推导中可能有多个for循环。

multiple_for_loops.py

#!/usr/bin/python3

a = [1, 2, 3]
b = ['A', 'B', 'C']

c = [ str(i) + j for i in a for j in b]
print(c)

该示例创建两个列表的笛卡尔乘积。

c = [ str(i) + j for i in a for j in b]

两个for循环用于创建笛卡尔乘积。

$ ./multiple_for_loops.py 
['1A', '1B', '1C', '2A', '2B', '2C', '3A', '3B', '3C']

这是示例的输出。

下一个示例显示如何展平 Python 列表。

flatten_list.py

#!/usr/bin/python3

nums = [[1, 2, 3], [3, 4, 5], [6, 7, 8]]

c = [ e for num in nums for e in num]
print(c)

nums列表是嵌套列表的列表。 我们用列表推导式来使列表扁平化。

c = [ e for num in nums for e in num]

第一个循环遍历外部列表。 第二个for循环遍历嵌套列表。

$ ./flatten_list.py 
[1, 2, 3, 3, 4, 5, 6, 7, 8]

这是示例的输出。

Python 嵌套列表推导式

Python 列表推导式中的初始表达式可以是另一个列表推导式。

nested_list_comprehension.py

#!/usr/bin/python3

M1 = [[1, 2, 3],
      [4, 5, 6],
      [7, 8, 9]]

M1_tr = [[row[i] for row in M1] for i in range(3)]
print(M1_tr)

该示例定义一个矩阵,列表推导从原始矩阵创建一个转置矩阵。

$ ./nested_list_comprehension.py 
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

这是示例的输出。

Eratosthenes 筛

Eratosthenes 的筛子是一种古老的计算素数的算法。 质数(或素数)是大于 1 的自然数,除 1 及其本身外没有除数。 该算法将每个素数的倍数从 2 的倍数开始迭代标记为复合(即不是素数)。

sieve_of_eratosthenes.py

#!/usr/bin/python3

no_primes = [j for i in range(2, 8) for j in range(i*2, 100, i)]
primes = [e for e in range(2, 100) if e not in no_primes]
print (primes)

该示例计算的质数最大为 100。

no_primes = [j for i in range(2, 8) for j in range(i*2, 100, i)]

首先,我们创建一个不是素数的数字列表。

primes = [e for e in range(2, 100) if e not in no_primes]

质数就是这些没有包含在no_primes列表中的数字。

$ ./sieve_of_eratosthenes.py 
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

这是输出。

在本教程中,我们介绍了 Python 列表推导。

您可能还会对以下相关教程感兴趣: Python 教程Python lambda 函数OpenPyXL 教程Python SimpleJson 教程,[ Python CSV 教程Python Requests 教程

{% raw %}

Python 魔术方法

原文: http://zetcode.com/python/magicmethods/

Python 魔术方法教程描述了什么是 Python 魔术方法,并说明了如何使用它们。 在本教程中,我们介绍了一些常见的魔术方法。

Python 魔术方法

Python 魔术方法是为我们的自定义类添加功能的特殊方法。 它们被双下划线包围(例如__add __())。

Python 中有许多魔术方法。 它们中的大多数用于非常特殊的情况。 我们将提到一些更流行的方法。

__add__方法

__add__()方法用于实现加法运算。 在 Python 中,数字不是原始字面值,而是对象。 num + 4表达式等效于num.__add__(4)

add_dict.py

#!/usr/bin/env python

class MyDict(dict):

    def __add__(self, other):

        self.update(other)
        return MyDict(self)

a = MyDict({'de': 'Germany'})
b = MyDict({'sk': 'Slovakia'})

print(a + b)

在示例中,我们有一个自定义字典,该字典使用__add__()实现加法运算。

class MyDict(dict):

def __add__(self, other):

    self.update(other)
    return MyDict(self)

自定义字典继承自内置dict__add__()方法与update()方法添加两个字典,并返回新创建的字典。

a = MyDict({'de': 'Germany'})
b = MyDict({'sk': 'Slovakia'})

我们创建两个简单的字典。

print(a + b)

我们添加两个字典。

$ ./add_dict.py
{'de': 'Germany', 'sk': 'Slovakia'}

这是输出。

__init____str__方法

__init__()方法用于初始化对象。 此方法用于实现对象的构造器。 __str__()提供了对象可读的输出。

init_str.py

#!/usr/bin/env python

class Person:

    def __init__(self, name, occupation):

        self.name = name
        self.occupation = occupation

    def __str__(self):

        return f'{self.name} is a {self.occupation}'

p = Person('John Doe', 'gardener')
print(p)

在示例中,我们有一个Person类,具有两个属性:nameoccupation

def __init__(self, name, occupation):

    self.name = name
    self.occupation = occupation

__init__()方法中,我们将实例变量设置为传递给构造器的值。

def __str__(self):

    return f'{self.name} is a {self.occupation}'

__str__()方法可以很好地输出对象。

$ ./init_str.py
John Doe is a gardener

这是输出。

__repr__方法

__repr__()方法由内置函数repr()调用。 当它求值返回对象的表达式时,在 Python shell 上使用它。

__str__()用于提供对象的人类可读版本,__repr__()用于提供对象的完整表示。 后者的输出也更适合开发者。

如果缺少__str__()实现,则将__repr__()方法用作后备。

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

对象的__repr__()方法的默认实现类似于上面的代码。

repr_ex.py

#!/usr/bin/env python

class Person:

    def __init__(self, name, occupation):

        self.name = name
        self.occupation = occupation

    def __str__(self):

        return f'{self.name} is a {self.occupation}'

    def __repr__(self):

        return f'Person{{name: {self.name}, occupation: {self.occupation}}}'

p = Person('John Doe', 'gardener')

print(p)
print(repr(p))

该示例实现了__str__()__repr__()方法。

$ ./repr_ex.py
John Doe is a gardener
Person{name: John Doe, occupation: gardener}

这是输出。

__len____getitem__方法

__len__()方法返回容器的长度。 当我们在对象上使用内置的len()方法时,将调用该方法。 __getitem__()方法定义项目访问([])运算符。

french_deck.py

#!/usr/bin/env python

import collections
from random import choice

Card = collections.namedtuple('Card', ['suit', 'rank'])

class FrenchDeck:

    ranks = [str(i) for i in range(2, 11)] + list('JQKA')
    suits = ["heart", "clubs", "spades", "diamond"]

    def __init__(self):
        self.total = [Card(suit, rank)
                           for suit in self.suits for rank in self.ranks]

    def __len__(self):
        return len(self.total)

    def __getitem__(self, index):
        return self.total[index]

deck = FrenchDeck()

print(deck[0])
print(len(deck))
print(choice(deck))

该方法用于实现法语卡片组。

Card = collections.namedtuple('Card', ['suit', 'rank'])

我们使用一个命名的元组来定义一个Card类。 namedtuple是用于创建元组类的工厂功能。 每张卡都有一套西装和一个等级。

def __len__(self):
    return len(self.total)

__len__()方法返回卡座(52)中的卡数。

def __getitem__(self, index):
    return self.total[index]

__getitem__()实现索引操作。

print(deck[0])

我们得到卡组的第一张牌。 这称为__getitem__()

print(len(deck))

这将调用__len__()方法。

$ ./french_deck.py
Card(suit='heart', rank='2')
52
Card(suit='diamond', rank='A')

这是输出。

__int____index__方法

调用__int__()方法以实现内置的int()函数。 当在切片表达式中使用对象以及内置的hex()oct()bin()函数时,__index__()方法将类型转换为int

char_ex.py

#!/usr/bin/env python

class Char:

    def __init__(self, val):
        self.val = val

    def __int__(self):
        return ord(self.val)

    def __index__(self):
        return ord(self.val)

c1 = Char('a')

print(int(c1))
print(hex(c1))
print(bin(c1))
print(oct(c1))

在示例中,我们创建一个自定义的Char类,该类实现了int()hex()bin()oct()函数。

./char_ex.py
97
0x61
0b1100001
0o141

这是输出。

__eq ____ lt____gt__方法

__eq__()实现了==运算符。 __lt__()实现了<运算符,__gt__()实现了>运算符。

pouch.py

#!/usr/bin/env python

import collections

Coin = collections.namedtuple('coin', ['rank'])

# a gold coin equals to two silver and six bronze coins

class Pouch:

    def __init__(self):
        self.bag = []

    def add(self, coin):

        self.bag.append(coin)

    def __eq__(self, other):

        val1, val2 = self.__evaluate(other)

        if val1 == val2:
            return True
        else:
            return False

    def __lt__(self, other):

        val1, val2 = self.__evaluate(other)

        if val1 < val2:
            return True
        else:
            return False

    def __gt__(self, other):

        val1, val2 = self.__evaluate(other)

        if val1 > val2:
            return True
        else:
            return False

    def __str__(self):

        return str(self.bag)

    def __evaluate(self, other):

        val1 = 0
        val2 = 0

        for coin in self.bag:

            if coin.rank == 'g':
                val1 += 6

            if coin.rank == 's':
                val1 += 3

            if coin.rank == 'b':
                val1 += 1

        for coin in other.bag:

            if coin.rank == 'g':
                val2 += 6

            if coin.rank == 's':
                val2 += 3

            if coin.rank == 'b':
                val2 += 1

        return val1, val2

pouch1 = Pouch()

pouch1.add(Coin('g'))
pouch1.add(Coin('g'))
pouch1.add(Coin('s'))

pouch2 = Pouch()

pouch2.add(Coin('g'))
pouch2.add(Coin('s'))
pouch2.add(Coin('s'))
pouch2.add(Coin('b'))
pouch2.add(Coin('b'))
pouch2.add(Coin('b'))

print(pouch1)
print(pouch2)

if pouch1 == pouch2:
    print('Pouches have equal value')

elif pouch1 > pouch2:
    print('Pouch 1 is more valueable than Pouch 2')
else:
    print('Pouch 2 is more valueable than Pouch 1')

我们有一个可以容纳金,银和青铜硬币的小袋。 一枚金币等于两个银币和六个铜币。 在示例中,我们使用 Python 魔术方法为pouch对象实现了三个比较运算符。

def __eq__(self, other):

    val1, val2 = self.__evaluate(other)

    if val1 == val2:
        return True
    else:
        return False

__eq__()方法中,我们首先求值两个小袋的值。 然后我们比较它们并返回布尔结果。

def __evaluate(self, other):

    val1 = 0
    val2 = 0

    for coin in self.bag:

        if coin.rank == 'g':
            val1 += 6

        if coin.rank == 's':
            val1 += 3

        if coin.rank == 'b':
            val1 += 1

    for coin in other.bag:

        if coin.rank == 'g':
            val2 += 6

        if coin.rank == 's':
            val2 += 3

        if coin.rank == 'b':
            val2 += 1

    return val1, val2

__evaluate()方法计算两个袋的值。 它穿过小袋的硬币,并根据硬币的等级增加一个值。

pouch1 = Pouch()

pouch1.add(Coin('g'))
pouch1.add(Coin('g'))
pouch1.add(Coin('s'))

我们创建第一个袋,并在其中添加三个硬币。

if pouch1 == pouch2:
    print('Pouches have equal value')

elif pouch1 > pouch2:
    print('Pouch 1 is more valueable than Pouch 2')
else:
    print('Pouch 2 is more valueable than Pouch 1')

我们将小袋与比较运算符进行比较。

2D 向量示例

在下面的示例中,我们介绍了几种其他魔术方法,包括__sub__()__mul__()__abs__()

vector.py

#!/usr/bin/env python

import math

class Vec2D:

    def __init__(self, x, y):

        self.x = x
        self.y = y

    def __add__(self, other):
        return Vec2D(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Vec2D(self.x - other.x, self.y - other.y)

    def __mul__(self, other):
        return self.x * other.x + self.y * other.y

    def __abs__(self):
        return math.sqrt(self.x ** 2 + self.y ** 2)

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __str__(self):
        return f'({self.x}, {self.y})'

    def __ne__(self, other):
        return not self.__eq__(other)  

u = Vec2D(0, 1)
v = Vec2D(2, 3)
w = Vec2D(-1, 1)

a = u + v
print(a)

print(a == w)

a = u - v
print(a)

a = u * v

print(a)
print(abs(u))
print(u == v)
print(u != v)

在示例中,我们有一个Vec2D类。 我们可以比较,加,减和乘向量。 我们还可以计算向量的长度。

$ ./vector.py
(2, 4)
False
(-2, -2)
3
1.0
False 
True

这是输出。

在本教程中,我们使用了 Python 魔术方法。

您可能也对以下相关教程感兴趣: Python 字符串Python Jinja 教程Python 教程,或列出所有 Python 教程

{% endraw %}

PyQt 中的QPropertyAnimation

原文: http://zetcode.com/pyqt/qpropertyanimation/

PyQt 中的 QPropertyAnimation 显示了如何使用QPropertyAnimation在 PyQt 中创建动画。 在示例中,我们对对象的大小,颜色和位置进行了动画处理。 来源和球图像可以在作者的 Github 仓库中找到。

QPropertyAnimation

QPropertyAnimation内插 PyQt 属性。 声明属性的类必须为为QObject

QPropertyAnimation方法

下表显示了一些重要的QPropertyAnimation方法:

名称 描述
start() 开始动画
stop() 终止动画
setStartValue() 设置动画的起始值
setEndValue() 设置动画的结束值
setDuration() 设置动画的持续时间,以毫秒为单位
setKeyValueAt() 在给定步骤以给定值创建关键帧
setLoopCount() 设置动画的重复次数

使用QPropertyAnimation设置动画大小

在第一个示例中,我们为小部件的大小设置动画。

size_anim.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
ZetCode Advanced PyQt5 tutorial 

This program animates the size of a
widget with QPropertyAnimation.

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
'''

from PyQt5.QtWidgets import QWidget, QApplication, QFrame, QPushButton
from PyQt5.QtCore import QRect, QPropertyAnimation
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.button = QPushButton("Start", self)
        self.button.clicked.connect(self.doAnim)
        self.button.move(30, 30)

        self.frame = QFrame(self)
        self.frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
        self.frame.setGeometry(150, 30, 100, 100)

        self.setGeometry(300, 300, 380, 300)
        self.setWindowTitle('Animation')
        self.show()        

    def doAnim(self):

        self.anim = QPropertyAnimation(self.frame, b"geometry")
        self.anim.setDuration(10000)
        self.anim.setStartValue(QRect(150, 30, 100, 100))
        self.anim.setEndValue(QRect(150, 30, 200, 200))
        self.anim.start()

if __name__ == "__main__":

    app = QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

该示例对QFrame小部件的大小进行动画处理。

self.button = QPushButton("Start", self)
self.button.clicked.connect(self.doAnim)
self.button.move(30, 30)

动画以QPushButton开始。

self.anim = QPropertyAnimation(self.frame, b"geometry")

QPropertyAnimation已创建。 第一个参数是要动画的目标对象; 在我们的例子中,我们为QFrame小部件设置了动画。 第二个参数是将要更改的属性。

self.anim.setDuration(10000)

setDuration()设置动画的持续时间(以毫秒为单位)。

self.anim.setStartValue(QRect(150, 30, 100, 100))
self.anim.setEndValue(QRect(150, 30, 200, 200))

使用setStartValue()setEndValue()分别定义动画的开始和结束值。

self.anim.start()

动画从start()方法开始。

使用QPropertyAnimation设置颜色的动画

下面的示例对小部件的颜色进行动画处理。 由于没有颜色属性,因此我们必须创建一个。

color_anim.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
ZetCode Advanced PyQt5 tutorial 

This programs animates the color of a QLabel.

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
'''

from PyQt5.QtWidgets import (QWidget, QApplication, QPushButton, 
        QLabel, QHBoxLayout, QSizePolicy)
from PyQt5.QtGui import QColor
from PyQt5.QtCore import QPropertyAnimation, pyqtProperty
import sys

class MyLabel(QLabel):

    def __init__(self, text):
        super().__init__(text)

    def _set_color(self, col):

        palette = self.palette()
        palette.setColor(self.foregroundRole(), col)
        self.setPalette(palette)

    color = pyqtProperty(QColor, fset=_set_color)

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):     

        hbox = QHBoxLayout(self)

        self.button = QPushButton("Start", self)
        self.button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        hbox.addWidget(self.button)

        hbox.addSpacing(40)

        self.label = MyLabel("Summer")
        font = self.label.font()
        font.setPointSize(35)
        self.label.setFont(font)
        hbox.addWidget(self.label)

        self.anim = QPropertyAnimation(self.label, b"color")
        self.anim.setDuration(2500)
        self.anim.setLoopCount(2)
        self.anim.setStartValue(QColor(0, 0, 0))
        self.anim.setEndValue(QColor(255, 255, 255))

        self.button.clicked.connect(self.anim.start)

        self.setGeometry(300, 300, 380, 250)
        self.setWindowTitle('Color anim')
        self.show()    

if __name__ == "__main__":

    app = QApplication([])
    ex = Example()
    ex.show()
    app.exec_()

该示例逐渐更改QLabel的颜色值。

class MyLabel(QLabel):

    def __init__(self, text):
        super().__init__(text)

    def _set_color(self, col):

        palette = self.palette()
        palette.setColor(self.foregroundRole(), col)
        self.setPalette(palette)

    color = pyqtProperty(QColor, fset=_set_color)

QLabel没有颜色属性; 因此,我们用pyqtProperty定义一个。 更改此属性将更新标签的颜色。

self.anim = QPropertyAnimation(self.label, b"color")

QPropertyAnimation更改标签窗口小部件的color属性。

self.anim.setLoopCount(2)

使用setLoopCount()方法,我们可以更改动画运行的次数。

self.anim.setStartValue(QColor(0, 0, 0))
self.anim.setEndValue(QColor(255, 255, 255))

我们设置开始和结束颜色值。

使用QPropertyAnimation沿曲线动画

以下示例使球沿贝塞尔曲线动画。

anim_along_curve.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
ZetCode Advanced PyQt5 tutorial

This programs animates a ball object 
along a curve.

Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
'''

from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QPainter, QPixmap, QPainterPath
from PyQt5.QtCore import QObject, QPointF, QPropertyAnimation, pyqtProperty
import sys

class Ball(QLabel):

    def __init__(self, parent):
        super().__init__(parent)

        pix = QPixmap("ball.png")
        self.h = pix.height()
        self.w = pix.width()

        self.setPixmap(pix)

    def _set_pos(self, pos):

        self.move(pos.x() - self.w/2, pos.y() - self.h/2)

    pos = pyqtProperty(QPointF, fset=_set_pos)   

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initView()
        self.initAnimation()

    def initView(self):    

        self.path = QPainterPath()
        self.path.moveTo(30, 30)
        self.path.cubicTo(30, 30, 200, 350, 350, 30)        

        self.ball = Ball(self)

        self.ball.pos = QPointF(30, 30)

        self.setWindowTitle("Animation along curve")
        self.setGeometry(300, 300, 400, 300)
        self.show()

    def paintEvent(self, e):    

        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing)   
        qp.drawPath(self.path)
        qp.end()             

    def initAnimation(self):

        self.anim = QPropertyAnimation(self.ball, b'pos')
        self.anim.setDuration(7000)

        self.anim.setStartValue(QPointF(30, 30))

        vals = [p/100 for p in range(0, 101)]

        for i in vals:
            self.anim.setKeyValueAt(i, self.path.pointAtPercent(i))  

        self.anim.setEndValue(QPointF(350, 30))        
        self.anim.start()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

该示例在窗口上绘制一条曲线。 沿绘制的曲线为球对象设置动画。

class Ball(QLabel):

    def __init__(self, parent):
        super().__init__(parent)

        pix = QPixmap("ball.png")
        self.h = pix.height()
        self.w = pix.width()

        self.setPixmap(pix)

球显示在QLabel小部件中。

def _set_pos(self, pos):

    self.move(pos.x() - self.w/2, pos.y() - self.h/2)

pos = pyqtProperty(QPointF, fset=_set_pos)   

我们调整球的位置; 我们希望将标签的中间放置在曲线上。

self.path = QPainterPath()
self.path.moveTo(30, 30)
self.path.cubicTo(30, 30, 200, 350, 350, 30) 

贝塞尔曲线是用QPainterPath创建的。 其cubicTo()方法以起点,控制点和终点为参数。

def paintEvent(self, e):    

    qp = QPainter()
    qp.begin(self)
    qp.setRenderHint(QPainter.Antialiasing)   
    qp.drawPath(self.path)
    qp.end() 

paintEvent()方法中使用drawPath()方法绘制曲线。

self.anim = QPropertyAnimation(self.ball, b'pos')

我们用QPropertyAnimation为球的pos属性设置动画。

vals = [p/100 for p in range(0, 101)]

通过 Python 列表推导式,我们创建了动画步骤列表。 步长是介于 0 和 1 之间的值。

for i in vals:
    self.anim.setKeyValueAt(i, self.path.pointAtPercent(i))  

使用setKeyValueAt(),我们定义给定步骤中球的位置。 使用pointAtPercent(),我们可以在路径的给定百分比处获得QPointF

Animation along curve

图:沿曲线的动画

图形视图框架中的QPropertyAnimation

QPropertyAnimation可以在 Graphics View Framework 中为图形项目设置动画。 动画对象必须继承自QObjectQGraphicsItem

gvf_anim.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
ZetCode Advanced PyQt5 tutorial

This programs animates a ball object. 

Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
'''

from PyQt5.QtWidgets import (QApplication, QGraphicsView, 
        QGraphicsPixmapItem, QGraphicsScene)
from PyQt5.QtGui import QPainter, QPixmap
from PyQt5.QtCore import (QObject, QPointF, 
        QPropertyAnimation, pyqtProperty)
import sys

class Ball(QObject):

    def __init__(self):
        super().__init__()

        self.pixmap_item = QGraphicsPixmapItem(QPixmap("ball.png"))

    def _set_pos(self, pos):
        self.pixmap_item.setPos(pos)

    pos = pyqtProperty(QPointF, fset=_set_pos)        

class Example(QGraphicsView):

    def __init__(self):
        super().__init__()

        self.initView()

    def initView(self):    

        self.ball = Ball()

        self.anim = QPropertyAnimation(self.ball, b'pos')
        self.anim.setDuration(8000)
        self.anim.setStartValue(QPointF(5, 30))

        self.anim.setKeyValueAt(0.3, QPointF(80, 30))                   
        self.anim.setKeyValueAt(0.5, QPointF(200, 30))
        self.anim.setKeyValueAt(0.8, QPointF(250, 250))

        self.anim.setEndValue(QPointF(290, 30))

        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, 300, 300)
        self.scene.addItem(self.ball.pixmap_item)
        self.setScene(self.scene)

        self.setWindowTitle("Ball animation")
        self.setRenderHint(QPainter.Antialiasing)        
        self.setGeometry(300, 300, 500, 350)

        self.anim.start()

        self.show()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

该示例在 Graphics View Framework 中使用QPropertyAnimation为球对象设置动画。

class Ball(QObject):

    def __init__(self):
        super().__init__()

        self.pixmap_item = QGraphicsPixmapItem(QPixmap("ball.png"))

    def _set_pos(self, pos):
        self.pixmap_item.setPos(pos)

    pos = pyqtProperty(QPointF, fset=_set_pos) 

Sice PyQt 不支持多重继承,我们使用合成技术来满足前面提到的条件。

class Example(QGraphicsView):

    def __init__(self):
        super().__init__()

        self.initView()

QGraphicsView在可滚动视口中可视化QGraphicsScene的内容。

self.anim = QPropertyAnimation(self.ball, b'pos')

我们将使用QPropertyAnimation为球对象的position属性设置动画。

self.anim.setDuration(8000)

动画持续八秒钟。

self.anim.setKeyValueAt(0.3, QPointF(80, 30))                   
self.anim.setKeyValueAt(0.5, QPointF(200, 30))
self.anim.setKeyValueAt(0.8, QPointF(250, 250))

使用setKeyValueAt()方法,我们在给定步骤创建具有给定值的关键帧。 换句话说,我们定义了动画给定步骤中球的位置。

self.scene = QGraphicsScene(self)
self.scene.setSceneRect(0, 0, 300, 300)
self.scene.addItem(self.ball.pixmap_item)

创建QGraphicsScene并将球添加到场景中。 它提供了一个用于管理大量 2D 图形项目的界面。 注意,我们将ball属性添加到场景中,而不是ball对象。

在本教程中,我们使用QPropertyAnimation创建了动画。

您可能也对以下相关教程感兴趣: PyQt5 教程QNetworkAccessManager教程Python 教程

PyQt 中的QNetworkAccessManager

原文: http://zetcode.com/pyqt/qnetworkaccessmanager/

PyQt 教程中的QNetworkAccessManager展示了如何显示如何使用QNetworkAccessManager发送请求和接收响应。

QNetworkAccessManager

QNetworkAccessManager允许应用发送网络请求和接收回复。 QNetworkRequest保留要与网络管理器发送的请求,QNetworkReply包含返回的数据和响应头。

QNetworkAccessManager具有异步 API,这意味着其方法总是立即返回,并且不等到完成时才返回。 而是在请求完成时发出信号。 我们通过附加到完成信号的方法来处理响应。

HTTP GET 请求

HTTP GET 方法请求指定资源的表示形式。

get_request.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
QNetworkAccessManager in PyQt

In this example we get a web page.

Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''

from PyQt5 import  QtNetwork
from PyQt5.QtCore import QCoreApplication, QUrl
import sys

class Example:

    def __init__(self):    

        self.doRequest()

    def doRequest(self):   

        url = "http://www.something.com"
        req = QtNetwork.QNetworkRequest(QUrl(url))

        self.nam = QtNetwork.QNetworkAccessManager()
        self.nam.finished.connect(self.handleResponse)
        self.nam.get(req)    

    def handleResponse(self, reply):

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            bytes_string = reply.readAll()
            print(str(bytes_string, 'utf-8'))

        else:
            print("Error occured: ", er)
            print(reply.errorString())

        QCoreApplication.quit()    

app = QCoreApplication([])
ex = Example()
sys.exit(app.exec_())

该示例检索指定网页的 HTML 代码。

url = "http://www.something.com"
req = QtNetwork.QNetworkRequest(QUrl(url))

使用QNetworkRequest,我们将请求发送到指定的 URL。

self.nam = QtNetwork.QNetworkAccessManager()
self.nam.finished.connect(self.handleResponse)
self.nam.get(req)  

创建一个QNetworkAccessManager对象。 请求完成后,将调用handleResponse()方法。 使用get()方法触发该请求。

def handleResponse(self, reply):

    er = reply.error()

    if er == QtNetwork.QNetworkReply.NoError:

        bytes_string = reply.readAll()
        print(str(bytes_string, 'utf-8'))

    else:
        print("Error occured: ", er)
        print(reply.errorString())

    QCoreApplication.quit()    

handleResponse()接收QNetworkReply对象。 它包含已发送请求的数据和标头。 如果网络回复中没有错误,我们将使用readAll()方法读取所有数据; 否则,我们将显示错误消息。 errorString()返回人类可读的最后发生的错误的描述。 readAll()返回QByteArray中必须解码的数据。

$ ./get_request.py 
<html><head><title>Something.</title></head>
<body>Something.</body>
</html>

这是输出。

HTTP POST 请求

HTTP POST 方法将数据发送到服务器。 请求正文的类型由Content-Type标头指示。 POST 请求通常通过 HTML 表单发送。 请求中发送的数据可以采用不同的方式进行编码。 在application/x-www-form-urlencoded中,值被编码为以'&'分隔的键值元组,键和值之间带有'='。 非字母数字字符采用百分比编码。 multipart/form-data用于二进制数据和文件上传。

post_request.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
QNetworkAccessManager in PyQt

In this example we post data to a web page.

Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''

from PyQt5 import QtCore, QtGui, QtNetwork
import sys, json     

class Example:

    def __init__(self):    

        self.doRequest()

    def doRequest(self):   

        data = QtCore.QByteArray()
        data.append("name=Peter&")
        data.append("age=34")

        url = "https://httpbin.org/post"
        req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
        req.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, 
            "application/x-www-form-urlencoded")

        self.nam = QtNetwork.QNetworkAccessManager()
        self.nam.finished.connect(self.handleResponse)
        self.nam.post(req, data)    

    def handleResponse(self, reply):

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            bytes_string = reply.readAll()

            json_ar = json.loads(str(bytes_string, 'utf-8'))
            data = json_ar['form']

            print('Name: {0}'.format(data['name']))
            print('Age: {0}'.format(data['age']))

            print()

        else:
            print("Error occurred: ", er)
            print(reply.errorString())

        QtCore.QCoreApplication.quit()    

app = QtCore.QCoreApplication([])
ex = Example()
sys.exit(app.exec_())

该示例将发布请求发送到https://httpbin.org/post测试站点,该站点将数据以 JSON 格式发送回。

data = QtCore.QByteArray()
data.append("name=Peter&")
data.append("age=34")

根据规范,我们对QByteArray中发送的数据进行编码。

url = "https://httpbin.org/post"
req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))
req.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, 
    "application/x-www-form-urlencoded")

我们指定application/x-www-form-urlencoded编码类型。

bytes_string = reply.readAll()

json_ar = json.loads(str(bytes_string, 'utf-8'))
data = json_ar['form']

print('Name: {0}'.format(data['name']))
print('Age: {0}'.format(data['age']))

print()

在处理器方法中,我们读取响应数据并将其解码。 使用内置的json模块,我们提取发布的数据。

$ ./post_request.py 
Name: Peter
Age: 34

这是输出。

使用QNetworkAccessManager进行认证

每当最终服务器在传递所请求的内容之前请求认证时,都会发出authenticationRequired信号。

authenticate.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
QNetworkAccessManager in PyQt

In this example, we show how to authenticate
to a web page.

Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''

from PyQt5 import QtCore, QtGui, QtNetwork
import sys, json

class Example:

    def __init__(self):    

        self.doRequest()

    def doRequest(self):   

        self.auth = 0

        url = "https://httpbin.org/basic-auth/user7/passwd7"
        req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))

        self.nam = QtNetwork.QNetworkAccessManager()
        self.nam.authenticationRequired.connect(self.authenticate)
        self.nam.finished.connect(self.handleResponse)
        self.nam.get(req)  

    def authenticate(self, reply, auth):

        print("Authenticating")

        self.auth += 1

        if self.auth >= 3:
            reply.abort()

        auth.setUser("user7")
        auth.setPassword("passwd7")         

    def handleResponse(self, reply):

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            bytes_string = reply.readAll()

            data = json.loads(str(bytes_string, 'utf-8'))

            print('Authenticated: {0}'.format(data['authenticated']))
            print('User: {0}'.format(data['user']))

            print()

        else:
            print("Error occurred: ", er)
            print(reply.errorString())

        QtCore.QCoreApplication.quit()    

app = QtCore.QCoreApplication([])
ex = Example()
sys.exit(app.exec_())

在示例中,使用https://httpbin.org网站显示如何使用QNetworkAccessManager进行认证。

self.nam.authenticationRequired.connect(self.authenticate)

我们将authenticationRequired信号连接到authenticate()方法。

def authenticate(self, reply, auth):

    print("Authenticating")
    ...

authenticate()方法的第三个参数是QAuthenticator,用于传递所需的认证信息。

self.auth += 1

if self.auth >= 3:
    reply.abort()

如果验证失败,则QNetworkAccessManager会继续发出authenticationRequired信号。 在三次失败的尝试之后,我们中止了该过程。

auth.setUser("user7")
auth.setPassword("passwd7")

我们将用户和密码设置为QAuthenticator

bytes_string = reply.readAll()

data = json.loads(str(bytes_string, 'utf-8'))

print('Authenticated: {0}'.format(data['authenticated']))
print('User: {0}'.format(data['user']))

print()

https://httpbin.org用 JSON 数据响应,该数据包含用户名和指示认证成功的布尔值。

$ ./authenticate.py 
Authenticating
Authenticated: True
User: user7

这是输出。

提取一个网站图标

网站图标是与特定网站相关的小图标。 在以下示例中,我们将从网站上下载网站图标。

fetch_icon.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

'''
QNetworkAccessManager in PyQt

In this example we fetch a favicon from 
a website.

Author: Jan Bodnar
Website: zetcode.com
Last edited: September 2017
'''

from PyQt5 import QtCore, QtGui, QtNetwork
import sys    

class Example:

    def __init__(self):    

        self.doRequest()

    def doRequest(self):   

        url = "http://www.google.com/favicon.ico"
        req = QtNetwork.QNetworkRequest(QtCore.QUrl(url))

        self.nam = QtNetwork.QNetworkAccessManager()
        self.nam.finished.connect(self.handleResponse)
        self.nam.get(req)    

    def handleResponse(self, reply):

        er = reply.error()

        if er == QtNetwork.QNetworkReply.NoError:

            data = reply.readAll()
            self.saveFile(data)        

        else:
            print("Error occured: ", er)
            print(reply.errorString())

        QtCore.QCoreApplication.quit()    

    def saveFile(self, data):

        f = open('favicon.ico', 'wb')

        with f:

            f.write(data)

app = QtCore.QCoreApplication([])
ex = Example()
sys.exit(app.exec_())

该代码示例下载了 Google 的收藏夹图标。

self.nam.get(req)   

我们使用get()方法下载图标。

data = reply.readAll()
self.saveFile(data)   

handleResponse()方法中,我们读取数据并将其保存到文件中。

def saveFile(self, data):

    f = open('favicon.ico', 'wb')

    with f:

        f.write(data)

图像数据以saveFile()方法保存在磁盘上。

在本教程中,我们使用了QNetworkAccessManager

您可能也对以下相关教程感兴趣: QPropertyAnimation教程PyQt5 教程Python 教程

Python 字符串

原文: http://zetcode.com/lang/python/strings/

在 Python 编程教程的这一部分中,我们将更详细地处理字符串数据。

Python 字符串定义

Python 中的字符串是字符序列。 它是派生的数据类型。 字符串是不可变的。 这意味着一旦定义,就无法更改。 许多 Python 方法,例如replace()join()split()都会修改字符串。 但是,它们不会修改原始字符串。 他们创建一个字符串副本,然后对其进行修改并返回给调用者。

Python 字符串字面值

可以使用单引号,双引号或三引号创建 Python 字符串。 当我们使用三引号时,字符串可以跨越多行而无需使用转义符。

string_literals.py

#!/usr/bin/env python

# string_literals.py

a = "proximity alert"
b = 'evacuation'
c = """
requiem 
for
a 
tower
"""

print(a)
print(b)
print(c)

在我们的示例中,我们为abc变量分配了三个字符串字面值。 然后将它们打印到控制台。

$ ./string_literals.py 
proximity alert
evacuation

requiem 
for 
a 
tower

Python 中的 Unicode

如果要创建 Unicode 字符串,请在文本开头添加uU字符。

unicode.py

#!/usr/bin/env python

# unicode.py

text = u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\
\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\
\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'

print(text)

在我们的示例中,我们在西里尔字母中打​​印了托尔斯泰:《安娜·卡列尼娜》。

$ ./unicode.py 
Лев Николаевич Толстой: 
Анна Каренина

如果我们使用编码注释,则可以直接使用俄语字母。

unicode2.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

# unicode2.py

text = 'Лев Николаевич Толстой: Анна Каренина'

print(text)

在此示例中,我们直接在源代码中使用非拉丁字符。 我们定义了带有编码注释的 UTF-8 编码。

在 Python 中使用引号

Python 中的字符串由单引号或双引号字符分隔。 如果我们想显示报价,例如直接讲话怎么办? 有两种基本方法可以做到这一点。

quotes.py

#!/usr/bin/env python

# quotes.py

print("There are many stars.")
print("He said, \"Which one is your favourite?\"")

print('There are many stars.')
print('He said, "Which one is your favourite?"')

我们使用\字符转义其他引号。 通常,双引号用于分隔字符串字面值。 但是,当转义时,其原始含义被抑制。 它显示为普通字符,可以在字符串字面值中使用。 在引号中使用引号的第二种方法是混合单引号和双引号。

$ ./quotes.py
There are many stars.
He said, "Which one is your favourite?"
There are many stars.
He said, "Which one is your favourite?"

这是输出。

Python 字符串长度

len()方法计算字符串中的字符数。 空白字符也算在内。

string_length.py

#!/usr/bin/env python

# string_length.py

s1 = "Eagle"
s2 = "Eagle\n"
s3 = "Eagle  "

print(len(s1))
print(len(s2))
print(len(s3))

我们计算三个字符串的长度。

s1 = "Eagle"
s2 = "Eagle\n"
s3 = "Eagle  "

定义了三个字符串。 第二个字符串的末尾有换行符。 第三个有两个额外的空格字符。

print(len(s1))

我们将字符数打印到控制台。

$ ./length.py
5
6
7

从输出中我们可以看到,空格(在本例中为换行符和空格符)也被计算在内。

Python 字符串剥离空白字符

在字符串处理中,我们通常可能会以在字符串开头或结尾处带有空白字符的字符串结尾。 术语空白(字符)是指不可见的字符,例如换行符,制表符,空格或其他控制字符。 我们有strip()lstrip()rstrip()方法来删除这些字符。

stripping.py

#!/usr/bin/env python

# strippig.py

s = " Eagle  "

s2 = s.rstrip()
s3 = s.lstrip()
s4 = s.strip()

print('{0} {1}'.format(s, len(s)))
print('{0} {1}'.format(s2, len(s2)))
print('{0} {1}'.format(s3, len(s3)))
print('{0} {1}'.format(s4, len(s4)))

我们对具有三个空格的字符串单词应用剥离方法。 开头一个空格,结尾两个空格。 请注意,这些方法会删除任意数量的空格,而不仅仅是一个空格。

s2 = s.rstrip()

rstrip()方法返回一个字符串,其中删除了结尾的空白字符。

s3 = s.lstrip()

lstrip()方法返回一个字符串,其中删除了前导空格字符。

s4 = s.strip()

strip()方法返回字符串的副本,其中删除了前导和尾随字符。

print('{0} {1}'.format(s2, len(s2)))

format()方法用于动态构建字符串。 {0}是引用format()方法第一个参数的控制字符。 {1}是指第二个参数。

$ ./stripping.py 
 Eagle   8
 Eagle 6
Eagle   7
Eagle 5

这是stripping.py示例的输出。

Python 字符串转义序列

在处理字符串时,可以使用转义序列。 转义序列是特殊字符,在字符串中使用时具有特定目的。

print("   bbb\raaa") # prints aaabbb

回车\r是行尾到行首的控制字符。

strophe.py

#!/usr/bin/env python

# strophe.py

print("Incompatible, it don't matter though\n'cos someone's bound to hear my cry")
print("Speak out if you do\nYou're not easy to find")

新行是控制字符,它开始新的一行文本。

$ ./strophe.py 
Incompatible, it don't matter though
'cos someone's bound to hear my cry
Speak out if you do
You're not easy to find

接下来,我们检查退格控制字符。

print("Python\b\b\booo") # prints Pytooo

退格控制字符\b将光标向后移动一个字符。 在本例中,我们使用三个退格字符删除三个字母,并用三个o字符替换它们。

print("Towering\tinferno") # prints Towering        inferno

水平选项卡在文本之间放置一个空格。

"Johnie's dog"
'Johnie\'s dog'

单引号和双引号可以嵌套。 或者,如果仅使用单引号,则可以使用反斜杠来转义单引号的默认含义。

如果我们在字符串前面加上r,则会得到原始字符串。 转义序列不被解释。

raw.py

#!/usr/bin/env python

# raw.py

print(r"Another world\n")

$ ./raw.py 
Another world\n

我们得到的字符串包括换行符。

Python 比较字符串

比较字符串是编程中的常见工作。 我们可以使用==运算符比较两个字符串。 我们可以用非等式!=运算符检查相反的情况。 运算符返回布尔TrueFalse

comparing.py

#!/usr/bin/env python

# comparing.py

print("12" == "12")
print("17" == "9")
print("aa" == "ab")

print("abc" != "bce")
print("efg" != "efg")

在此代码示例中,我们比较了一些字符串。

print("12" == "12")

这两个字符串相等,因此该行返回True

print("aa" == "ab")

两个字符串的前两个字符相等。 接下来比较以下字符。 它们不同,因此该行返回False

print("abc" != "bce")

由于两个字符串不同,因此该行返回True

$ ./comparing.py
True
False
False
True
False

这是输出。

Python 访问字符串元素

可以在 Python 中访问字符串元素。

string_elements.py

#!/usr/bin/env python

# string_elements.py

s = "Eagle"

print(s[0])
print(s[4])
print(s[-1])
print(s[-2])

print("****************")

print(s[0:4])
print(s[1:3])
print(s[:])

索引操作用于获取字符串的元素。

print(s[0])
print(s[4])

第一行打印第一个字符。 第二行打印第五个字符。 索引从零开始。

print(s[-1])
print(s[-2])

当索引为负数时,我们从字符串的末尾检索元素。 在这种情况下,我们将打印最后一个字符和最后一个字符。

print(s[0:4])

也可以访问字符范围。 该行打印从第一个字符开始到第四个字符结束的一系列字符。

print(s[:])

此行将打印字符串中的所有字符。

$ ./string_elements.py
E
e
e
l
****************
Eagl
ag
Eagle

这是输出。

for循环可用于遍历字符串的所有字符。

traverse.py

#!/usr/bin/env python

# traverse.py

s = "ZetCode"

for i in s:
  print(i, " ", end="")

该脚本将给定字符串的所有字符打印到控制台。

$ ./traverse.py
Z e t C o d e

这是输出。

Python 查找子字符串

find()rfind()index()rindex()方法用于查找字符串中的子字符串。 它们返回第一次出现的子字符串的索引。 find()index()方法从字符串的开头搜索。 rfind()rindex()从字符串的末尾开始搜索。

find()index()方法之间的区别在于,当找不到子字符串时,前者返回 -1。 后者引发ValueError异常。

find(str, beg=0, end=len(string))
rfind(str, beg=0, end=len(string))
index(str, beg=0, end=len(string))
rindex(str, beg=0, end=len(string))

str是要搜索的子字符串。 beg参数是起始索引,默认值为 0。end参数是终止索引。 默认情况下,它等于字符串的长度。

substrings.py

#!/usr/bin/env python

# substrings.py

a = "I saw a wolf in the forest. A lone wolf."

print(a.find("wolf"))
print(a.find("wolf", 10, 20))
print(a.find("wolf", 15))

print(a.rfind("wolf"))

我们有一个简单的句子。 我们尝试在句子中找到子字符串的索引。

print(a.find("wolf"))

该行查找句子中子字符串"wolf"的第一次出现。 打印 8。

print(a.find("wolf", 10, 20))

该行尝试查找"wolf"子字符串。 它从第 10 个字符开始,然后搜索接下来的 20 个字符。 在此范围内没有这样的子字符串,因此该行显示 -1(未找到)。

print(a.find("wolf", 15))

在这里,我们搜索从第 15 个字符到字符串结尾的子字符串。 我们找到子字符串的第二次出现。 该行打印 35。

print(a.rfind("wolf"))

rfind()从末尾查找子字符串。 它查找"wolf"子字符串的第二次出现。 该行打印 35。

$ ./substrings.py
8
-1
35
35

这是输出。

在第二个示例中,我们将使用index()rindex()方法。

substrings2.py

#!/usr/bin/env python

# substrings2.py

a = "I saw a wolf in the forest. A lone wolf."

print(a.index("wolf"))
print(a.rindex("wolf"))

try:
    print(a.rindex("fox"))
except ValueError as e:
    print("Could not find substring")

在示例中,我们使用index()rindex()方法搜索子字符串。

print(a.index("wolf"))
print(a.rindex("wolf"))

这些行从开头和结尾开始查找"wolf"子字符串的第一个匹配项。

try:
    print(a.rindex("fox"))
except ValueError as e:
    print("Could not find substring")

当找不到子字符串时,rindex()方法引发ValueError异常。

$ ./substrings2.py
8
35
Could not find substring

这是示例的输出。

Python 基本字符串操作

在下一个示例中,我们将进行字符串乘法和连接。

add_multiply.py

#!/usr/bin/env python

# add_multiply.py

print("eagle " * 5)

print("eagle " "falcon")

print("eagle " + "and " + "falcon")

*运算符将字符串重复 n 次。 在我们的情况下是五次。 彼此相邻的两个字符串字面值会自动连接在一起。 我们还可以使用+运算符显式连接字符串。

$ ./add_multiply.py 
eagle eagle eagle eagle eagle 
eagle falcon
eagle and falcon

这是add_multiply.py脚本的输出。

我们可以使用len()函数来计算字符串的长度(以字符为单位)。

eagle.py

#!/usr/bin/python

# eagle.py

var = 'eagle'

print(var, "has", len(var), "characters")

在示例中,我们计算字符串变量中的字符数。

$ ./eagle.py 
eagle has 5 characters

一些编程语言允许隐式添加字符串和数字。 在 Python 语言中,这是不可能的。 我们必须显式转换值。

string_number.py

#!/usr/bin/python

# string_number.py

print(int("12") + 12)
print("There are " + str(22) + " oranges.")
print(float('22.33') + 22.55)

我们使用内置的int()函数将字符串转换为整数。 并且还有一个内置的str()函数将数字转换为字符串。 然后,我们使用float()函数将字符串转换为浮点数。

Python 替换字符串

replace()方法将字符串中的子字符串替换为其他子字符串。 由于 Python 中的字符串是不可变的,因此将使用替换的值构建新的字符串。

replace(old, new [, max])

默认情况下,replace()方法将替换所有出现的子字符串。 该方法采用第三个参数,它将替换次数限制为一定数量。

replacing.py

#!/usr/bin/env python

# replacing.py

a = "I saw a wolf in the forest. A lonely wolf."

b = a.replace("wolf", "fox")
print(b)

c = a.replace("wolf", "fox", 1)
print(c)

我们有一句话用"fox"代替"wolf"

b = a.replace("wolf", "fox")

该行将所有出现的"wolf"替换为"fox"

c = a.replace("wolf", "fox", 1)

在这里,我们仅替换第一次出现的情况。

$ ./replacing.py
I saw a fox in the forest. A lonely fox.
I saw a fox in the forest. A lonely wolf.

这是输出。

Python 分割和连接字符串

可以使用split()rsplit()方法分割字符串。 它们返回使用分隔符从字符串中切出的字符串列表。 可选的第二个参数是允许的最大分割数。

splitting.py

#!/usr/bin/env python

# splitting.py

nums = "1,5,6,8,2,3,1,9"

k = nums.split(",")
print(k)

l = nums.split(",", 5)
print(l)

m = nums.rsplit(",", 3)
print(m)

我们有一个逗号分隔的字符串。 我们把绳子切成小段。

k = nums.split(",")

我们使用逗号作为分隔符将字符串分成八个部分。 该方法返回八个字符串的列表。

l = nums.split(",", 5)

在这里,我们将字符串分成六个部分。 有五个子字符串,其余部分为字符串。

m = nums.rsplit(",", 3)

在这里,我们将字符串分成四个部分。 这次拆分是从右侧进行的。

$ ./splitting.py
['1', '5', '6', '8', '2', '3', '1', '9']
['1', '5', '6', '8', '2', '3,1,9']
['1,5,6,8,2', '3', '1', '9']

字符串可以与join()字符串连接。 它返回由作为参数传递的字符串连接而成的字符串。 元素之间的分隔符是提供此方法的字符串。

split_join.py

#!/usr/bin/env python

# split_join.py

nums = "1,5,6,8,2,3,1,9"

n = nums.split(",")
print(n)

m = ':'.join(n)
print(m)

首先,我们将字符串拆分为字符串列表。 然后,我们将字符串连接到一个字符串中,并用提供的字符分隔元素。

m = ':'.join(n)

join()方法从字符串列表中创建一个字符串。 元素由:字符分隔。

$ ./split_join.py
['1', '5', '6', '8', '2', '3', '1', '9']
1:5:6:8:2:3:1:9

这是输出。

可以用于分割字符串的另一种方法是partition()。 它将在第一次出现分隔符时分割字符串,并返回一个三元组,其中包含分隔符之前的部分,分隔符本身以及分隔符之后的部分。

partition.py

#!/usr/bin/env python

# partition.py

s = "1 + 2 + 3 = 6"

a = s.partition("=")

print(a)

在此示例中,我们使用partition()方法。

a = s.partition("=")

这会将字符串切成三部分。 =字符前的一个,分隔符,分隔符的右边。

$ ./partition.py
('1 + 2 + 3 ', '=', ' 6')

这是输出。

Python 字符串大小写

Python 有四种处理字符串大小写的字符串方法。 这些方法返回一个新的修改后的字符串。

convert_case.py

#!/usr/bin/env python

# convert_case.py

a = "ZetCode"

print(a.upper())
print(a.lower())
print(a.swapcase())
print(a.title())

我们有一个字符串词,我们将在上面演示这四种方法。

print(a.upper())

upper()方法返回字符串的副本,其中所有字符均转换为大写。

print(a.lower())

在这里,我们以小写字母获取字符串的副本。

print(a.swapcase())

swapcase()方法交换字母的大小写。 小写字符将变为大写,反之亦然。

print(a.title())

title()方法返回字符串的副本,其中第一个字符为大写,其余字符为小写。

$ ./convert_case.py
ZETCODE
zetcode
zETcODE
Zetcode

这是输出。

对字符串的 Python 操作

有几个有用的内置函数可用于处理字符串。

letters.py

#!/usr/bin/env python

# letters.py

sentence = "There are 22 apples"

alphas = 0
digits = 0
spaces = 0

for i in sentence:

   if i.isalpha():
      alphas += 1

   if i.isdigit():
      digits += 1

   if i.isspace():
      spaces += 1

print("There are", len(sentence), "characters")
print("There are", alphas, "alphabetic characters")
print("There are", digits, "digits")
print("There are", spaces, "spaces")

在我们的示例中,我们有一个字符串句子。 我们计算句子中的绝对字符数,字母字符数,数字和空格。 为此,我们使用以下函数:len()isalpha()isdigit()isspace()

$ ./letters.py 
There are 19 characters
There are 14 alphabetic characters
There are 2 digits
There are 3 spaces

在下一个示例中,我们将打印足球比赛的结果。

teams1.py

#!/usr/bin/env python

# teams1.py

print("Ajax Amsterdam" " - " "Inter Milano " "2:3")
print("Real Madridi" " - " "AC Milano " "3:3")
print("Dortmund" " - " "Sparta Praha " "2:1")

我们已经知道相邻的字符串是连接在一起的。

$ ./teams1.py 
Ajax Amsterdam - Inter Milano 2:3
Real Madridi - AC Milano 3:3
Dortmund - Sparta Praha 2:1

接下来,我们将改善输出的外观。

teams2.py

#!/usr/bin/env python

# teams2.py

teams = { 
      0: ("Ajax Amsterdam", "Inter Milano"),
      1: ("Real Madrid", "AC Milano"),
      2: ("Dortmund", "Sparta Praha")
}

results = ("2:3", "3:3", "2:1")

for i in teams:

   line = teams[i][0].ljust(16) + "-".ljust(5) + teams[i][1].ljust(16) + results[i].ljust(3)
   print(line)

ljust()方法返回左对齐字符串,rjust()方法返回右对齐字符串。 如果字符串小于我们提供的宽度,则将用空格填充。

$ ./teams2.py 
Ajax Amsterdam  -    Inter Milano    2:3
Real Madrid     -    AC Milano       3:3
Dortmund        -    Sparta Praha    2:1

现在输出看起来更好。

Python 字符串格式化

字符串格式化是将各种值动态地放入字符串中。 可以使用%运算符或format()方法实现字符串格式化。

oranges.py

#!/usr/bin/env python

# oranges.py

print('There are %d oranges in the basket' % 32)
print('There are {0} oranges in the basket'.format(32))

在代码示例中,我们动态构建一个字符串。 我们在句子中加上数字。

print('There are %d oranges in the basket' % 32)

我们使用%d格式说明符。 d字符表示我们期望一个整数。 在字符串之后,我们放置一个模运算符和一个参数。 在这种情况下,我们有一个整数值。

print('There are {0} oranges in the basket'.format(32))

使用format()方法可以完成相同的任务。 这次,格式化说明符是{0}

$ ./oranges.py 
There are 32 oranges in the basket
There are 32 oranges in the basket

下一个示例显示如何向字符串中添加更多值。

fruits.py

#!/usr/bin/env python

# fruits.py

print('There are %d oranges and %d apples in the basket' % (12, 23))
print('There are {0} oranges and {1} apples in the basket'.format(12, 23))

在这两行中,我们添加了两个格式说明符。

$ ./fruits.py 
There are 12 oranges and 23 apples in the basket
There are 12 oranges and 23 apples in the basket

在下一个示例中,我们构建一个带有浮点数和字符串值的字符串。

height.py

#!/usr/bin/env python

# height.py

print('Height: %f %s' % (172.3, 'cm'))
print('Height: {0:f} {1:s}'.format(172.3, 'cm'))

我们打印一个人的身高。

print('Height: %f %s' % (172.3, 'cm'))

浮点值的格式说明符为%f,字符串为%s

print('Height: {0:f} {1:s}'.format(172.3, 'cm'))

使用format()方法,我们将fs字符添加到说明符中。

$ ./height.py 
Height: 172.300000 cm
Height: 172.300000 cm

我们可能不喜欢上面示例中的数字默认情况下具有 6 个小数位的事实。 我们可以控制格式说明符中的小数位数。

height2.py

#!/usr/bin/env python

# height2.py

print('Height: %.2f %s' % (172.3, 'cm'))
print('Height: {0:.2f} {1:s}'.format(172.3, 'cm'))

小数点后跟一个整数控制小数位数。 在我们的情况下,该数字将保留两位小数。

$ ./height2.py 
Height: 172.30 cm
Height: 172.30 cm

下面的示例显示其他格式设置选项。

various.py

#!/usr/bin/python

# various.py

# hexadecimal
print("%x" % 300)
print("%#x" % 300)

# octal
print("%o" % 300)

# scientific
print("%e" % 300000)

前两种格式使用十六进制数。 x字符将以十六进制格式格式化数字。 #字符会将0x添加到十六进制数字。 o字符以八进制格式显示数字。 e字符将以科学格式显示数字。

$ ./various.py 
12c
0x12c
454
3.000000e+05

format()方法还支持二进制格式。

various2.py

#!/usr/bin/python

# various2.py

# hexadecimal
print("{:x}".format(300))
print("{:#x}".format(300))

# binary
print("{:b}".format(300))

# octal
print("{:o}".format(300))

# scientific
print("{:e}".format(300000))

该示例以十六进制,二进制,八进制和科学格式打印数字。

下一个示例将打印三列数字。

columns1.py

#!/usr/bin/env python

# columns1.py

for x in range(1, 11):
    print('%d %d %d' % (x, x*x, x*x*x))

数字左对齐,输出不是最佳的。

$ ./columns1.py 
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000

为了解决这个问题,我们使用宽度说明符。 宽度说明符定义对象的最小宽度。 如果对象小于宽度,则将填充空格。

columns2.py

#!/usr/bin/env python

# columns2.py

for x in range(1, 11):
    print('%2d %3d %4d' % (x, x*x, x*x*x))

现在输出看起来正常。 值 2 使第一列宽 2 个字符。

$ ./columns2.py 
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

现在我们有了format()方法的改进格式。

columns3.py

#!/usr/bin/env python

# columns3.py

for x in range(1, 11):
    print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))

Python 教程的这一章专门介绍 Python 中的字符串数据类型。

Python 列表

原文: http://zetcode.com/lang/python/lists/

在 Python 编程教程的这一部分中,我们将更详细地介绍 Python 列表。

Python 列表定义

列表是值的有序集合。 它可以包含各种类型的值。 列表是可变容器。 这意味着我们可以添加值,删除值或修改现有值。

Python 列表表示有限序列的数学概念。 列表的值称为列表的项目或元素。 列表可以多次包含相同的值。 每次出现都被视为不同的项目。

Python 列表索引

列表元素可以通过其索引进行访问。 第一个元素的索引为 0,最后一个元素的索引为 -1。

simple.py

#!/usr/bin/env python

# simple.py

nums = [1, 2, 3, 4, 5]
print(nums)

这是一个包含五个元素的简单列表。 该列表由方括号[]分隔。 列表的元素由逗号分隔。 列表的内容将打印到控制台。

$ ./simple.py
[1, 2, 3, 4, 5]

这是示例的输出。

列表可以包含各种数据类型的元素。

various_types.py

#!/usr/bin/env python

# various_types.py

class Being:
    pass

objects = [1, -2, 3.4, None, False, [1, 2], "Python", (2, 3), Being(), {}]
print(objects)

在示例中,我们创建一个对象列表。 它包含数字,布尔值,另一个列表,字符串,元组,自定义对象和字典。

$ ./various_types.py 
[1, -2, 3.4, None, False, [1, 2], 'Python', (2, 3), 
    <__main__.Being instance at 0x7f653577f6c8>, {}]

这是输出。

Python 列表初始化

有时我们需要预先初始化一个列表以具有特定数量的元素。

initialization.py

#!/usr/bin/env python

n1 = [0 for i in range(15)]
n2 = [0] * 15

print(n1)
print(n2)

n1[0:11] = [10] * 10

print(n1)

在此示例中,我们使用列表推导和*运算符初始化了两个列表。

n1 = [0 for i in range(15)]
n2 = [0] * 15

这两个列表被初始化为十五个零。

n1[0:11] = [10] * 10

前十个值将替换为 10s。

$ ./initialization.py
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0]

这是示例输出。

Python 列表函数

list()函数从可迭代对象创建列表。 可迭代的对象可以是序列,支持迭代的容器或迭代器对象。 如果未指定任何参数,则创建一个新的空列表。

list_fun.py

#!/usr/bin/env python

# list_fun.py

a = []
b = list()

print(a == b)

print(list((1, 2, 3)))
print(list("ZetCode"))
print(list(['Ruby', 'Python', 'Perl']))

在示例中,我们创建一个空列表,一个元组列表,一个字符串和另一个列表。

a = []
b = list()

这是创建空列表的两种方法。

print(a == b)

该行打印True。 这证实了ab相等。

print(list((1, 2, 3)))

我们从 Python 元组创建一个列表。

print(list("ZetCode"))

该行从字符串生成列表。

print(list(['Ruby', 'Python', 'Perl']))

最后,我们创建一个字符串列表的副本。

$ ./list_fun.py
True
[1, 2, 3]
['Z', 'e', 't', 'C', 'o', 'd', 'e']
['Ruby', 'Python', 'Perl']

这是示例输出。

Python 列表操作

以下代码显示了一些基本的列表操作。

list_oper.py

#!/usr/bin/env python

# list_oper.py

n1 = [1, 2, 3, 4, 5]
n2 = [3, 4, 5, 6, 7]

print(n1 == n2)
print(n1 + n2)

print(n1 * 3)

print(2 in n1)
print(2 in n2)

我们定义了两个整数列表。 我们在这些列表上使用一些运算符。

print(n1 == n2)

列表的内容与==运算符进行比较。 由于元素不同,该行打印False

print(n1 + n2)

添加n1n2列表以形成新列表。 新列表包含两个列表的所有元素。

print(n1 * 3)

我们在列表上使用乘法运算符。 它重复元素 n 次; 在我们的情况下是三遍。

print(2 in n1)

我们使用in运算符来找出列表中是否存在该值。 它返回布尔值TrueFalse

$ ./lists.py
False
[1, 2, 3, 4, 5, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
True
False

运行示例将给出此输出。

Python 序列函数

序列函数可用于任何序列类型,包括列表。

sequence_funs.py

#!/usr/bin/env python

# sequence_funs.py

n = [1, 2, 3, 4, 5, 6, 7, 8]

print("There are {0} items".format(len(n)))
print("Maximum is {0}".format(max(n)))
print("Minimum is {0}".format(min(n)))
print("The sum of values is {0}".format(sum(n)))

在上面的示例中,我们具有四个函数:len()max()min()sum()

print("There are {0} items".format(len(n)))

len()函数返回列表的大小。 列表中元素的数量。

print("Maximum is {0}".format(max(n)))
print("Minimum is {0}".format(min(n)))

max()min()函数返回列表的最大值和最小值。

print("The sum of values is {0}".format(sum(n)))

sum()函数计算n列表中数字的总和。

$ ./sequence_funs.py
There are 8 items
Maximum is 8
Minimum is 1
The sum of values is 36

这是输出。

Python 添加列表元素

本节将显示如何将元素添加到 Python 列表中。

adding.py

#!/usr/bin/env python

# adding.py

langs = []

langs.append("Python")
langs.append("Perl")
print(langs)

langs.insert(0, "PHP")
langs.insert(2, "Lua")
print(langs)

langs.extend(("JavaScript", "ActionScript"))
print(langs)

我们可以通过三种方法将新元素添加到列表中:append()insert()extend()

langs = []

创建一个空列表。

langs.append("Python")
langs.append("Perl")

append()方法将一个项目添加到列表的末尾; 我们附加两个字符串。

langs.insert(0, "PHP")
langs.insert(2, "Lua")

insert()方法将元素放置在索引号指示的特定位置。 "PHP"字符串插入第一个位置,"Lua"字符串插入第三个位置。 请注意,列表索引号从零开始。

langs.extend(("JavaScript", "ActionScript"))

extend()方法将值的序列添加到列表的末尾。 在我们的例子中,两个 Python 元组字符串附加在列表的末尾。

$ ./adding.py
['Python', 'Perl']
['PHP', 'Python', 'Lua', 'Perl']
['PHP', 'Python', 'Lua', 'Perl', 'JavaScript', 'ActionScript']

这是示例输出。

IndexError

列表下标超出范围时,将引发IndexError

index_error.py

#!/usr/bin/env python

# index_error.py

n = [1, 2, 3, 4, 5]

try:

    n[0] = 10
    n[6] = 60

except IndexError as e:

    print(e)

在脚本中,我们定义了一个包含五个整数的列表。 这些元素的索引分别为 0、1、2、3 和 4。使用较大的索引会导致错误。

n[6] = 60

索引 6 超出了我们的列表范围。 抛出IndexError

except IndexError as e:

    print(e)

我们使用except子句捕获错误。 在子句的正文中,我们显示错误消息。

$ ./index_error.py
list assignment index out of range

这是示例输出。

TypeError

如果元组的索引不是纯整数,则会抛出TypeError

type_error.py

#!/usr/bin/env python

# type_error.py

n = [1, 2, 3, 4, 5]

try:
    print(n[1])
    print(n['2'])

except TypeError as e:

    print("Error in file {0}".format( __file__))
    print("Message: {0}".format(e))

本示例抛出一个TypeError

print(n['2'])

列表索引必须是整数。 其他类型以错误结尾。

except TypeError as e:

    print("Error in file {0}".format( __file__))
    print("Message: {0}".format(e))

except块中,我们打印发生异常的文件名和消息字符串。

$ ./typeerror.py
2
Error in file ./typeerror.py
Message: list indices must be integers, not str

这是示例输出。

从 Python 列表中删除元素

以前,我们已将项目添加到列表中。 现在,我们将从列表中删除它们。

removing.py

#!/usr/bin/env python

# removing.py

langs = ["Python", "Ruby", "Perl", "Lua", "JavaScript"]
print(langs)

lang = langs.pop(3)
print("{0} was removed".format(lang))

lang = langs.pop()
print("{0} was removed".format(lang))

print(langs)

langs.remove("Ruby")
print(langs)

pop()方法删除并返回具有指定索引的元素,如果没有给出索引号,则返回最后一个元素。 remove()方法从列表中删除特定项目。

lang = langs.pop(3)
print("{0} was removed".format(lang))

我们删除具有索引 3 的元素。pop()方法返回已删除元素的名称; 它被打印到控制台。

lang = langs.pop()
print("{0} was removed".format(lang))

列表中的最后一个元素,即"JavaScript"字符串,从列表中删除。

langs.remove("Ruby")

此行从langs列表中删除"Ruby"字符串。

['Python', 'Ruby', 'Perl', 'Lua', 'JavaScript']
Lua was removed
JavaScript was removed
['Python', 'Ruby', 'Perl']
['Python', 'Perl']

从脚本的输出中,我们可以看到所描述方法的效果。

del关键字也可用于删除列表元素。

removing2.py

#!/usr/bin/env python

# removing2.py

langs = ["Python", "Ruby", "Perl", "Lua", "JavaScript"]
print(langs)

del langs[1]
print(langs)

#del langs[15]

del langs[:]
print(langs)

我们有一个字符串列表。 我们使用del关键字删除列表元素。

del langs[1]

我们从列表中删除第二个字符串。 它是"Ruby"字符串。

#del langs[15]

我们只能删除现有元素。 如果取消注释代码行,我们将收到IndexError消息。

del langs[:]

在这里,我们从列表中删除所有剩余的元素。 [:]字符表示列表的所有项目。

$ ./removing2.py
['Python', 'Ruby', 'Perl', 'Lua', 'JavaScript']
['Python', 'Perl', 'Lua', 'JavaScript']
[]

这是示例输出。

Python 修改列表元素

在下一个示例中,我们将修改列表元素。

modifying.py

#!/usr/bin/env python

# modifying.py

langs = ["Python", "Ruby", "Perl"]

langs.pop(2)
langs.insert(2, "PHP")
print(langs)

langs[2] = "Perl"
print(langs)

在示例中,我们两次修改了langs列表的第三个元素。

langs.pop(2)
langs.insert(2, "PHP")

修改元素的一种方法是将其删除,然后将另一个元素放置在同一位置。

langs[2] = "Perl"

另一种方法更简单。 我们在给定位置分配一个新元素。 现在,在第三个位置再次有"Perl"字符串。

$ ./modifying.py
['Python', 'Ruby', 'PHP']
['Python', 'Ruby', 'Perl']

这是示例输出。

Python 复制列表

我们可以通过多种方式在 Python 中复制列表。 我们将提及其中的一些。

copying.py

#!/usr/bin/env python

# copying.py

import copy

w = ["Python", "Ruby", "Perl"]

c1 = w[:]
c2 = list(w)
c3 = copy.copy(w)
c4 = copy.deepcopy(w)
c5 = [e for e in w]

c6 = []

for e in w:
    c6.append(e)

c7 = []
c7.extend(w)

print(c1, c2, c3, c4, c5, c6, c7)

我们列出了三个字符串。 我们将列表复制了七次。

import copy

我们导入copy模块,其中有两种复制方法。

c1 = w[:]

使用切片语法复制列表。

c2 = list(w)

list()函数将列表作为参数时,它会创建一个列表副本。

c3 = copy.copy(w)
c4 = copy.deepcopy(w)

copy()方法产生列表的浅表副本。 deepcopy()产生列表的深层副本。

c5 = [e for e in w]

使用列表推导创建字符串的副本。

c6 = []

for e in w:
    c6.append(e)

for循环创建的副本。

c7 = []
c7.extend(w)

extend()方法也可用于创建副本。

$ ./copying.py
['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl'] 
['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl'] ['Python', 'Ruby', 'Perl'] 
['Python', 'Ruby', 'Perl']

使用不同的技术创建了一个字符串列表的七个副本。

Python 索引列表元素

Python 列表中的元素可以通过其索引进行访问。 索引号是整数; 他们从零开始。 索引可以是负数; 负索引是指列表末尾的元素。 列表中的第一项具有索引 0,最后一项具有-1。

indexing.py

#!/usr/bin/env python

# indexing.py

n = [1, 2, 3, 4, 5, 6, 7, 8]

print(n[0])
print(n[-1])
print(n[-2])

print(n[3])
print(n[5])

我们可以通过其索引访问列表的元素。 索引位于列表名称后方括号[]之间。

print(n[0])
print(n[-1])
print(n[-2])

这三行将打印列表的第一,最后和最后一个项目。

print(n[3])
print(n[5])

两行显示列表的第四和第六个元素。

$ ./indexing.py
1
8
7
4
6

这是示例输出。

index(e, start, end)方法查找特定元素并返回其最低索引。 startend是可选参数,它们将搜索限制到给定的边界。

indexing2.py

#!/usr/bin/env python

# indexing2.py

n = [1, 2, 3, 4, 1, 2, 3, 1, 2]

print(n.index(1))
print(n.index(2))

print(n.index(1, 1))
print(n.index(2, 2))

print(n.index(1, 2, 5))
print(n.index(3, 4, 8))

index()方法的代码示例。

print(n.index(1))
print(n.index(2))

这两行显示 n 列表中最左边的 1、2 值的索引。

print(n.index(1, 1))
print(n.index(2, 2))

在这里,我们在指定索引之后搜索值 1 和 2。

print(n.index(1, 2, 5))

在这里,我们在索引为 2 和 5 的值之间搜索值 1。

$ ./indexing2.py
0
1
4
5
4
6

这是示例输出。

Python 切片列表

列表切片是一种从列表中提取某些元素并将其形成另一个列表的操作。 可能具有不同数量的索引和不同的索引范围。

列表切片的语法如下:

[start:end:step]

语法的开始,结束,步骤部分是整数。 它们每个都是可选的。 它们可以是正面的也可以是负面的。 具有结束索引的值不包括在切片中。

slice.py

#!/usr/bin/env python

# slice.py

n = [1, 2, 3, 4, 5, 6, 7, 8]

print(n[1:5])
print(n[:5])
print(n[1:])
print(n[:])

我们从八个整数的列表中创建四个切片。

print(n[1:5])

第一个切片的索引值为 1、2、3 和 4。新形成的列表为[2, 3, 4, 5]

print(n[:5])

如果省略起始索引,则假定默认值为 0。切片为[1, 2, 3, 4, 5]

print(n[1:])

如果省略了结束索引,则采用-1 默认值。 在这种情况下,切片将所有值带到列表的末尾。

print(n[:])

甚至两个索引都可以忽略。 此语法创建列表的副本。

$ ./slice.py
[2, 3, 4, 5]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]

示例的输出。

切片语法中的第三个索引是步骤。 它允许我们从列表中获取第 n 个值。

slice2.py

#!/usr/bin/env python

# slice2.py

n = [1, 2, 3, 4, 5, 6, 7, 8]

print(n[1:9:2])
print(n[::2])
print(n[::1])
print(n[1::3])

我们使用step值形成四个新列表。

print(n[1:9:2])

在这里,我们创建一个切片,该切片具有从 n 列表开始的每个第二元素,从第二个元素开始,以第八个元素结束。 新列表具有以下元素:[2, 4, 6, 8]

print(n[::2])

在这里,我们通过获取列表开头到结尾的每个第二个值来构建切片。

print(n[::1])

这将创建一个列表的副本。

print(n[1::3])

切片具有第二个元素,从第二个元素到列表的末尾。

$ ./slice2.py
[2, 4, 6, 8]
[1, 3, 5, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[2, 5, 8]

示例的输出。

索引可以是负数。 负索引是指列表末尾的值。 最后一个元素的索引为-1,最后一个元素的索引为-2,依此类推。负数较小的索引必须在语法中排在首位。 这意味着我们写[-6, -2]而不是[-2, -6]。 后者返回一个空列表。

slice3.py

#!/usr/bin/env python

# slice3.py

n = [1, 2, 3, 4, 5, 6, 7, 8]

print(n[-4:-1])
print(n[-1:-4])

print(n[-5:])
print(n[-6:-2:2])
print(n[::-1])

在此脚本中,我们形成五个列表。 我们还使用负索引号。

print(n[-4:-1])
print(n[-1:-4])

第一行返回[5, 6, 7],第二行返回一个空列表。 较低的索引必须先于较高的索引。

print(n[::-1])

这将创建一个反向列表。

$ ./slice3.py
[5, 6, 7]
[]
[4, 5, 6, 7, 8]
[3, 5]
[8, 7, 6, 5, 4, 3, 2, 1]

示例的输出。

上面提到的语法可以在分配中使用。 赋值的右侧必须有一个可迭代的对象。

slice4.py

#!/usr/bin/env python

# slice4.py

n = [1, 2, 3, 4, 5, 6, 7, 8]

n[0] = 10
n[1:3] = 20, 30
n[3::1] = 40, 50, 60, 70, 80

print(n)

我们有八个整数的列表。 我们使用切片语法将元素替换为新值。

遍历 Python 列表

本节将指出在 Python 中遍历列表的三种基本方法。

traverse.py

#!/usr/bin/env python

# traverse.py

n = [1, 2, 3, 4, 5]

for e in n:
    print(e, end=" ")

print() 

第一个是遍历列表的最直接方法。

n = [1, 2, 3, 4, 5]

我们有一个数字列表。 列表中有五个整数。

for e in n:
    print(e, end=" ")

使用for循环,我们一张一张地浏览列表,然后将当前元素打印到控制台。

$ ./traverse.py
1 2 3 4 5

这是脚本的输出。 整数将打印到终端。

第二个示例更为详细。

traverse2.py

#!/usr/bin/env python

# traverse2.py

n = [1, 2, 3, 4, 5]

i = 0
s = len(n)

while i < s:

    print(n[i], end=" ")
    i = i + 1

print()

我们正在使用while循环遍历列表。

i = 0
l = len(n)

首先,我们需要定义一个计数器并找出列表的大小。

while i < s:

    print(n[i], end=" ")
    i = i + 1

在这两个数字的帮助下,我们遍历列表并将每个元素打印到终端。

enumerate()内置函数为我们提供了循环中列表的索引和值。

traverse3.py

#!/usr/bin/env python

# traverse3.py

n = [1, 2, 3, 4, 5]

print(list(enumerate(n)))

for e, i in enumerate(n):
    print("n[{0}] = {1}".format(e, i))

在示例中,我们打印值和值的索引。

$ ./traverse3.py 
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
n[0] = 1
n[1] = 2
n[2] = 3
n[3] = 4
n[4] = 5

运行脚本。

Python 计数列表元素

有时对列表元素进行计数很重要。 为此,Python 具有count()方法。

counting.py

#!/usr/bin/env python

# counting.py

n = [1, 1, 2, 3, 4, 4, 4, 5]

print(n.count(4))
print(n.count(1))
print(n.count(2))
print(n.count(6))

在此示例中,我们计算n列表中几个数字的出现次数。

n = [1, 1, 2, 3, 4, 4, 4, 5]

我们有一个整数列表。 整数 1 和 4 多次出现。

print(n.count(4))
print(n.count(1))
print(n.count(2))
print(n.count(6))

使用count()方法,我们发现 4、1、2 和 6 个数字的出现。

$ ./counting.py
3
2
1
0

数字 4 出现 3 次,1 次两次,2 次一次以及 6 在列表中不存在。

Python 嵌套列表

可以将列表嵌套到另一个列表中。 使用嵌套列表,将创建一个新维度。 要访问嵌套列表,需要附加的方括号[]

nested.py

#!/usr/bin/env python

# nested.py

nums = [[1, 2], [3, 4], [5, 6]]

print(nums[0])
print(nums[1])
print(nums[2])

print(nums[0][0])
print(nums[0][1])

print(nums[1][0])
print(nums[2][1])

print(len(nums))

在示例中,我们有三个嵌套列表,每个嵌套列表包含两个元素。

print(nums[0])
print(nums[1])
print(nums[2])

nums 列表的三个嵌套列表将打印到控制台。

print(nums[0][0])
print(nums[0][1])

在这里,我们打印第一个嵌套列表的两个元素。 nums[0]引用第一个嵌套列表; nums[0][0]引用第一个嵌套列表的第一个元素,即 1。

print(len(nums))

该行显示 3。每个嵌套列表都计为一个元素。 不考虑其内部元素。

$ ./nested.py
[1, 2]
[3, 4]
[5, 6]
1
2
3
6
3

这是示例输出。

第二个示例具有其他维度。

nested2.py

#!/usr/bin/env python

# nested2.py

nums = [[1, 2, [3, 4, [5, 6]]]]

print(nums[0])
print(nums[0][2])
print(nums[0][2][2])

print(nums[0][0])
print(nums[0][2][1])
print(nums[0][2][2][0])

在示例中,[5, 6]列表嵌套到[3, 4, ...]列表中,[3, 4, [4, 6]]嵌套到[1, 2, ...]列表中, 最终是nums列表的元素。

print(nums[0])
print(nums[0][2])
print(nums[0][2][2])

这三行将嵌套列表打印到控制台。

print(nums[0][0])
print(nums[0][2][1])
print(nums[0][2][2][0])

在此访问三个元素。 引用内部列表时,需要其他方括号[]

$ ./nested2.py
[1, 2, [3, 4, [5, 6]]]
[3, 4, [5, 6]]
[5, 6]
1
4
5

这是示例输出。

Python 排序列表

在本节中,我们对列表元素进行排序。 Python 具有用于执行排序的内置列表方法sort()sorted()函数。

sorting.py

#!/usr/bin/env python

# sorting.py

n = [3, 4, 7, 1, 2, 8, 9, 5, 6]
print(n)

n.sort()
print(n)

n.sort(reverse=True)
print(n)

在代码示例中,我们有一个未排序整数的列表。 我们使用sort()方法对元素进行排序。 该方法对元素进行原位排序; 原始列表已修改。

n.sort()

sort()方法以升序对元素进行排序。

n.sort(reverse=True)

将反向参数设置为True时,列表以降序排序。

$ ./sorting.py
[3, 4, 7, 1, 2, 8, 9, 5, 6]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1]

在输出中,我们可以看到原始列表,即按升序和降序排序的列表。

如果我们不想更改原始列表,可以使用sorted函数。 此函数创建一个新的排序列表。

sorting2.py

#!/usr/bin/env python

# sorting2.py

n = [3, 4, 1, 7, 2, 5, 8, 6]

print(n)
print(sorted(n))
print(n)

在示例中,我们使用sorted()函数对列表的元素进行排序。

$ ./sorting2.py
[3, 4, 1, 7, 2, 5, 8, 6]
[1, 2, 3, 4, 5, 6, 7, 8]
[3, 4, 1, 7, 2, 5, 8, 6]

从脚本的输出中,我们可以看到原始列表没有被修改。

sort()方法具有可选的key参数。 该参数指定在进行比较之前在每个列表元素上要调用的函数。

sorting3.py

#!/usr/bin/env python

# sorting3.py

words = ["big", "Blue", "seven", "glass", 
         "Green", "after", "Anctartica"]

words.sort()
print(words)

words.sort(key=str.lower)
print(words)

该示例产生区分大小写和不区分大小写的字符串比较。

words.sort(key=str.lower)

为了创建不区分大小写的比较,我们将str.lower函数添加到key参数中。

$ ./sorting3.py 
['Anctartica', 'Blue', 'Green', 'after', 'big', 'glass', 'seven']
['after', 'Anctartica', 'big', 'Blue', 'glass', 'Green', 'seven']

这是示例输出。

如果要对 Unicode 字符串进行排序,我们需要做其他工作。

sorting_locale.py

#!/usr/bin/env python

import locale
from functools import cmp_to_key

w = [u'zem', u'štebot', u'rum', u'železo', u'prameň', u"sob"]
locale.setlocale(locale.LC_COLLATE, ('sk_SK', 'UTF8'))

w.sort(key=cmp_to_key(locale.strcoll))

for e in w:
    print(e)

我们有六个 unicode 字符串的列表。 我们更改语言环境设置,以根据当前语言选项对字符串进行排序。

import locale
from functools import cmp_to_key

我们导入locale模块和cmp_to_key转换函数。

w = [u'zem', u'štebot', u'rum', u'železo', u'prameň', u"sob"]

这是六个字符串的列表。 字符串使用斯洛伐克语,并带有一些变音标记。 它们在正确排序字符方面发挥作用。

locale.setlocale(locale.LC_COLLATE, ('sk_SK', 'UTF8'))

我们为斯洛伐克语设置了语言环境。

w.sort(key=cmp_to_key(locale.strcoll))

我们对列表进行排序。 locale.strcoll根据当前LC_COLLATE设置比较两个字符串。 cmp_to_key函数将old-style比较函数转换为键函数。

for e in w:
    print(e)

我们将已排序的单词打印到控制台。

$ ./sorting_locale.py
prameň
rum
sob
štebot
zem
železo

元素已正确排序。 考虑了斯洛伐克字母的细节。

Python 反转列表元素

我们可以在 Python 中以几种方式反转列表中的元素。 反向元素不应与反向排序混淆。

reversing.py

#!/usr/bin/env python

# reversing.py

a1 = ["bear", "lion", "tiger", "eagle"]
a2 = ["bear", "lion", "tiger", "eagle"]
a3 = ["bear", "lion", "tiger", "eagle"]

a1.reverse()
print(a1)

it = reversed(a2)
r = list()

for e in it:
    r.append(e)

print(r)

print(a3[::-1])

在示例中,我们有三个相同的字符串列表。 我们以三种不同的方式反转元素。

a1.reverse()

第一种方法是使用reverse()方法。

it = reversed(a2)
r = list()

for e in it:
    r.append(e)

reversed()函数返回一个反向迭代器。 我们在for循环中使用迭代器,并创建一个新的反向列表。

print(a3[::-1])

第三种方法是使用slice语法反转列表,其中step参数设置为-1。

$ ./reversing.py
['eagle', 'tiger', 'lion', 'bear']
['eagle', 'tiger', 'lion', 'bear']
['eagle', 'tiger', 'lion', 'bear']

三个列表全部颠倒了。

Python 列表推导式

列表推导式是一种基于现有列表创建列表的语法结构。 语法受集合的数学符号的影响。 Python 语法受 Haskell 编程语言启发。

L = [expression for variable in sequence [if condition]]

上面的伪代码显示了列表推导式的语法。 列表推导式会创建一个新列表。 它基于现有列表。 for循环遍历整个序列。 对于每个循环,如果满足条件,则对表达式进行求值。 如果计算出该值,它将被添加到新列表中。 条件是可选的。

在可以使用map()filter()和/或嵌套循环的情况下,列表推导式为创建列表提供了一种更简洁的方法。

list_comprehension.py

#!/usr/bin/env python

# list_comprehension.py

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

b = [e for e in a if e % 2]
print(b)

在示例中,我们定义了一个数字列表。 在列表推导式的帮助下,我们创建了一个新的数字列表,这些数字不能除以 2 而没有余数。

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

这是九个整数的列表。

b = [e for e in a if e % 2]

这里我们有列表推导式。 在for e in a循环中,获取列表的每个元素。 然后测试if e % 2条件。 如果满足条件,则对表达式求值。 在我们的例子中,表达式是一个纯e,它直接使用元素。 最后,元素被添加到列表中。

$ ./list_comprehension.py
[1, 3, 5, 7, 9]

示例输出。 列表中的数字不能除以 2,不能有余数。

在第二个示例中,我们将列表推导式与传统的for循环进行了比较。

list_comprehension2.py

#!/usr/bin/env python

# list_comprehension2.py

lang = "Python"

a = []

for e in lang:
    a.append(ord(e))

b = [ord(e) for e in lang]

print(a)
print(b)

在示例中,我们有一个字符串。 我们要创建字符串字母的 ASCII 整数代码的列表。

a = []

for e in lang:
    a.append(ord(e))

我们使用for循环创建这样的列表。

b = [ord(e) for e in lang]

这里使用列表推导产生相同的结果。 注意,省略了if条件。 它是可选的。

$ ./list_comprehension2.py
[80, 121, 116, 104, 111, 110]
[80, 121, 116, 104, 111, 110]

这是示例输出。 您可以在 Python 列表推导教程中找到有关列表推导的更多信息。

Python 映射和过滤器函数

map()filter()函数是可在所有列表项上使用的质量函数。 它们是 Python 语言内置的函数编程的一部分。

今天,建议尽可能使用列表推导代替这些函数。

map_fun.py

#!/usr/bin/env python

# map_fun.py

def to_upper(s):

    return s.upper()

words = ["stone", "cloud", "dream", "sky"]

words2 = list(map(to_upper, words))
print(words2)

map()函数将特定函数应用于列表的每个元素。

def to_upper(s):

    return s.upper()

这是将应用于每个列表元素的函数的定义。 它在给定的字符串上调用upper()字符串方法。

words = ["stone", "cloud", "dream", "sky"]

这是字符串列表。

words2 = map(to_upper, words)
print(words2)

map()函数将to_upper()函数应用于单词列表的每个字符串元素。 形成一个新列表并返回。 我们将其打印到控制台。

$ ./map_fun.py
['STONE', 'CLOUD', 'DREAM', 'SKY']

列表中的每一项均以大写字母表示。

filter()函数从列表的那些元素中为函数返回true的列表构造一个列表。

filter_fun.py

#!/usr/bin/env python

# filter_fun.py

def positive(x):
    return x > 0

n = [-2, 0, 1, 2, -3, 4, 4, -1]

print(list(filter(positive, n)))

演示filter()函数的示例。 它将创建一个仅具有正值的新列表。 它将滤除所有负值和 0。

def positive(x):
    return x > 0

这是filter()函数使用的函数的定义。 返回TrueFalse。 返回布尔值的函数称为谓词。

$ ./filter_fun.py
[1, 2, 4, 4]

filter_fun.py脚本的输出。

在 Python 教程的这一部分中,我们描述了 Python 列表。

Python 字典

原文: http://zetcode.com/lang/python/dictionaries/

在 Python 编程教程的这一部分中,我们将更详细地介绍 Python 字典。

Python 字典是键-值对的容器。 它是可变的,可以包含混合类型。 字典是无序集合。 Python 字典在其他语言中称为关联数组或哈希表。 字典中的键必须是不可变的对象,例如字符串或数字。 它们在字典中也必须是唯一的。

Python 字典创建

首先,我们展示如何创建 Python 字典。

create_dict.py

#!/usr/bin/env python

# create_dict.py

weekend = { "Sun": "Sunday", "Mon": "Monday" }
vals = dict(one=1, two=2)

capitals = {}
capitals["svk"] = "Bratislava"
capitals["deu"] = "Berlin"
capitals["dnk"] = "Copenhagen"

d = { i: object() for i in range(4) }

print(weekend)
print(vals)
print(capitals)
print(d)

在示例中,我们以四种不同方式创建四个字典。 稍后,我们将这些字典的内容打印到控制台。

weekend = { "Sun": "Sunday", "Mon": "Monday" }

我们使用字典字面值表示法创建周末字典。 键值对用大括号括起来。 两对之间用逗号分隔。 一对的第一个值是键,后跟一个冒号和一个值。 "Sun"字符串是键,"Sunday"字符串是值。

vals = dict(one=1, two=2)

可以使用dict()函数创建字典。

capitals = {}
capitals["svk"] = "Bratislava"
capitals["deu"] = "Berlin"
capitals["dnk"] = "Copenhagen"

第三种方法是创建一个空的大写字典。 三对将添加到字典中。 键位于方括号内,值位于分配的右侧。

d = { i: object() for i in range(4) }

使用字典推导式来创建字典。 理解分为两个部分。 第一部分是i: object()表达式,该表达式在循环的每个循环中执行。 第二部分是for i in range(4)循环。 字典推导式将创建具有四对的字典,其中键为数字 0、1、2 和 3,值为简单对象。

$ ./create_dict.py
{'Sun': 'Sunday', 'Mon': 'Monday'}
{'two': 2, 'one': 1}
{'svk': 'Bratislava', 'dnk': 'Copenhagen', 'deu': 'Berlin'}
{0: <object object at 0xb76cb4a8>, 1: <object object at 0xb76cb4b0>,
2: <object object at 0xb76cb4b8>, 3: <object object at 0xb76cb4c0>}

这是示例输出。

Python 字典推导式

字典理解是一种基于现有字典创建字典的语法结构。

D = { expression for variable in sequence [if condition] }

字典推导式放在两个大括号之间; 它包含三个部分:for循环,条件和表达式。

for循环中,我们浏览了字典。 可选的if条件指定必须满足的条件。 最后,对表达式进行求值。 该表达式从满足条件的输入序列成员中产生输出字典的元素。

comprehension.py

#!/usr/bin/env python

# comprehension.py

capitals = { "Bratislava": 424207, "Vilnius": 556723, "Lisbon": 564657,
             "Riga": 713016, "Jerusalem": 780200, "Warsaw": 1711324,
             "Budapest": 1729040, "Prague": 1241664, "Helsinki": 596661,
             "Yokyo": 13189000, "Madrid": 3233527 }

capitals2 = { key:val for key, val in capitals.items() if val < 1000000 }

print(capitals2)

在示例中,我们从现有字典创建一个新字典。

capitals = { "Bratislava": 424207, "Vilnius": 556723, "Lisbon": 564657,
             "Riga": 713016, "Jerusalem": 780200, "Warsaw": 1711324,
             "Budapest": 1729040, "Prague": 1241664, "Helsinki": 596661,
             "Yokyo": 13189000, "Madrid": 3233527 }

我们有一个大写的字典。 键是大写的,而人口就是值。

capitals = { key:val for key, val in capitals.items() if val < 1000000 }

使用字典推导式来创建新字典。 它包含人口少于一百万的首都。

$ ./comprehension.py
{'Bratislava': 424207, 'Vilnius': 556723, 'Jerusalem': 780200, 'Riga': 713016,
    'Lisbon': 564657, 'Helsinki': 596661}

这些首都的人口少于一百万。

Python 字典的基本操作

以下示例显示了使用 Python 字典的一些基本操作。

basics.py

#!/usr/bin/env python

# basics.py

basket = { 'oranges': 12, 'pears': 5, 'apples': 4 }

basket['bananas'] = 5

print(basket)
print("There are {0} various items in the basket".format(len(basket)))

print(basket['apples'])
basket['apples'] = 8
print(basket['apples'])

print(basket.get('oranges', 'undefined'))
print(basket.get('cherries', 'undefined'))

我们有一个装着不同水果的篮子。 我们对购物篮字典执行一些操作。

basket = { 'oranges': 12, 'pears': 5, 'apples': 4 }

将创建篮子字典。 它最初具有三个键值对。

basket['bananas'] = 5

将创建一个新的配对。 'bananas'字符串是键,5整数是值。

print("There are {0} various items in the basket".format(len(basket)))

len()函数给出字典中的对数。

print(basket['apples'])

"apples"键的值会打印到终端上。

basket['apples'] = 8

"apples"键的值被修改。 设置为数字 8。

print(basket.get('oranges', 'undefined'))

get()方法检索指定键的值。 如果没有这样的键,则返回该方法的第二个参数。

print(basket.get('cherries', 'undefined'))

该行返回'undefined'。 篮子里没有樱桃。

$ ./basics.py
{'bananas': 5, 'pears': 5, 'oranges': 12, 'apples': 4}
There are 4 various items in the basket
4
8
12
undefined

这是示例输出。

Python 字典fromkeyssetdefault

下一个示例介绍了两种字典方法:fromkeys()setdefault()

fruits.py

#!/usr/bin/env python

# fruits.py

basket = ('oranges', 'pears', 'apples', 'bananas')

fruits = {}.fromkeys(basket, 0)
print(fruits)

fruits['oranges'] = 12
fruits['pears'] = 8
fruits['apples'] = 4

print(fruits.setdefault('oranges', 11))
print(fruits.setdefault('kiwis', 11))

print(fruits)

fromkeys()方法从列表创建一个新字典。 如果存在键,则setdefault()方法将返回一个值。 否则,它将插入具有指定默认值的键并返回该值。

basket = ('oranges', 'pears', 'apples', 'bananas')

我们有一个字符串列表。 从该列表中将构建新的字典。

fruits = {}.fromkeys(basket, 0)

fromkeys()方法创建一个新的字典,列表项将作为关键字。 每个键都将初始化为 0。请注意fromkeys()方法是一个类方法,需要调用该类名,在本例中为{}

fruits['oranges'] = 12
fruits['pears'] = 8
fruits['apples'] = 4

在这里,我们向fruits字典添加一些值。

print(fruits.setdefault('oranges', 11))
print(fruits.setdefault('kiwis', 11))

第一行将12打印到终端。 'oranges'键存在于字典中。 在这种情况下,该方法将返回其值。 在第二种情况下,键尚不存在。 一对新的'kiwis': 11被插入字典。 值11被打印到控制台。

$ ./fruits.py
{'bananas': 0, 'pears': 0, 'oranges': 0, 'apples': 0}
12
11
{'kiwis': 11, 'bananas': 0, 'pears': 8, 'oranges': 12, 'apples': 4}

当启动fruits.py脚本时,我们会收到此输出。

Python 字典更新方法

下一个代码示例演示如何使用update()方法添加两个 Python 字典。

domains.py

#!/usr/bin/env python

# domains.py

domains = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary"}
domains2 = { "us": "United States", "no": "Norway" }

domains.update(domains2)

print(domains)

两个字典通过update()方法结合在一起。

domains.update(domains2)

使用update()方法将domains2字典添加到域字典中。

$ ./domains.py
{'sk': 'Slovakia', 'de': 'Germany', 'no': 'Norway',
'us': 'United States', 'hu': 'Hungary'}

结果显示所有值。

Python 从字典中删除项目

现在我们展示如何从字典中删除一对。

removing.py

#!/usr/bin/env python

# removing.py

items = { "coins": 7, "pens": 3, "cups": 2,
    "bags": 1, "bottles": 4, "books": 5 }

print(items)

item = items.pop("coins")
print("Item having value {0} was removed".format(item))

print(items)

del items["bottles"]
print(items)

items.clear()
print(items)

项目字典有六个键值对。 我们将从该字典中删除配对。

item = items.pop("coins")
print("Item having value {0} was removed".format(item))

pop()方法删除具有指定键的一对; 它返回已删除键的值。

del items["bottles"]

del关键字从项目字典中删除"bottles": 4对。

items.clear()

clear()方法清除字典中的所有项目。

$ ./removing.py
{'bags': 1, 'pens': 3, 'coins': 7, 'books': 5, 'bottles': 4, 'cups': 2}
Item having value 7 was removed
{'bags': 1, 'pens': 3, 'books': 5, 'bottles': 4, 'cups': 2}
{'bags': 1, 'pens': 3, 'books': 5, 'cups': 2}
{}

这是示例输出。

Python 字典键和值

Python 字典由键值对组成。 keys()方法从字典中返回键列表。 values()方法创建一个值列表。 并且items()方法返回键值元组的列表。

keys_values.py

#!/usr/bin/env python

# keys_values.py

domains = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway"  }

print(domains.keys())
print(domains.values())
print(domains.items())

print("de" in domains)
print("cz" in domains)

我们演示了上述方法。 我们还检查in关键字是否存在键。

print(domains.keys())

我们使用keys()方法打印domains字典的键列表。

print(domains.values())

我们使用values()方法打印domains字典的值列表。

print(domains.items())

最后,我们使用items()方法打印域字典的键值元组列表。

print("de" in domains)
print("cz" in domains)

使用in关键字,我们检查domains字典中是否存在"de""cz"键。 返回值为TrueFalse

$ ./keys_values.py
['sk', 'de', 'no', 'us', 'hu']
['Slovakia', 'Germany', 'Norway', 'United States', 'Hungary']
[('sk', 'Slovakia'), ('de', 'Germany'), ('no', 'Norway'),
('us', 'United States'), ('hu', 'Hungary')]
True
False

示例的输出。

Python 字典循环

遍历字典是常见的编程工作。 这可以通过for关键字完成。

looping.py

#!/usr/bin/env python

# looping.py

domains = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway" }

for key in domains:
    print(key)

for val in domains.values():
    print(val)

for k, v in domains.items():
    print(": ".join((k, v)))

在该示例中,我们遍历domains字典以打印键,值以及字典的键和值。

for key in domains:
    print(key)

此循环将打印字典的所有键。

for val in domains.values():
    print(val)

第二个循环打印字典的所有值。

for k, v in domains.items():
    print(": ".join((k, v)))

在第三个循环中,将打印所有键和值。

$ ./looping.py
sk
de
no
us
hu
Slovakia
Germany
Norway
United States
Hungary
sk: Slovakia
de: Germany
no: Norway
us: United States
hu: Hungary

示例的输出。

Python 字典成员性测试

使用innot in运算符,我们可以检查字典中是否存在键。

membership.py

#!/usr/bin/env python

# membership.py

domains = { "de": "Germany", "sk": "Slovakia", "hu": "Hungary",
    "us": "United States", "no": "Norway"  }

key = "sk"

if key in domains:
    print("{0} is in the dictionary".format(domains[key]))

在示例中,我们使用in运算符检查国家/地区是否在字典中。

Python 字典排序

Python 字典是无序的。 这也意味着它们不能像 Python 列表那样排序。 程序员可以创建 Python 字典的排序表示形式。 在本节中,我们展示了几种创建排序输出的方法。

程序员可能希望以正常或相反的顺序对数据进行排序。 他们可以按键或按值对数据进行排序。

simple_sort.py

#!/usr/bin/env python

# simple_sort.py

items = { "coins": 7, "pens": 3, "cups": 2,
    "bags": 1, "bottles": 4, "books": 5 }

kitems = list(items.keys())
kitems.sort()

for k in kitems:
    print(": ".join((k, str(items[k]))))

第一个示例提供了最简单的解决方案,以按键对数据进行排序。

kitems = items.keys()
kitems.sort()

从字典中获得键列表。 该列表使用sort()方法排序。

for k in kitems:
    print(": ".join((k, str(items[k]))))

在循环中,我们从字典中打印排序的键以及它们的值。

$ ./simple_sort.py
bags: 1
books: 5
bottles: 4
coins: 7
cups: 2
pens: 3

项目字典按其键排序。

内置的sorted()函数可以完成更有效的分类。

sorting.py

#!/usr/bin/env python

# sorting.py

items = { "coins": 7, "pens": 3, "cups": 2,
    "bags": 1, "bottles": 4, "books": 5 }

for key in sorted(items.keys()):
    print("%{0}: {1}".format(key, items[key]))

print("###############")

for key in sorted(items.keys(), reverse=True):
    print("{0}: {1}".format(key, items[key]))

在示例中,我们使用sorted()函数按其键升序和降序打印排序的数据。

for key in sorted(items.keys()):
    print("%{0}: {1}".format(key, items[key]))

在此for循环中,我们打印按升序排序的对。 iteritems()函数在字典的(键,值)对上返回一个迭代器。

for key in sorted(items.keys(), reverse=True):
    print("{0}: {1}".format(key, items[key]))

在第二个for循环中,数据按降序排序。 订单类型由reverse参数控制。

$ ./sorting.py
bags: 1
books: 5
bottles: 4
coins: 7
cups: 2
pens: 3
###############
pens: 3
cups: 2
coins: 7
bottles: 4
books: 5
bags: 1

sorting.py脚本的输出。

在下一个示例中,我们将按项目的值对项目进行排序。

sorting2.py

#!/usr/bin/env python

# sorting2.py

items = { "coins": 7, "pens": 3, "cups": 2,
    "bags": 1, "bottles": 4, "books": 5 }

for key, value in sorted(items.items(), key=lambda pair: pair[1]):

    print("{0}: {1}".format(key, value))

print("###############")

for key, value in sorted(items.items(), key=lambda pair: pair[1], reverse=True):

    print("{0}: {1}".format(key, value))

该示例按值的升序和降序打印数据。

for key, value in sorted(items.iteritems(),
    key=lambda (k,v): (v,k)):

字典对按其值排序并打印到控制台。 key参数具有一个函数,该函数指示如何对数据进行排序。

$ ./sorting2.py
bags: 1
cups: 2
pens: 3
bottles: 4
books: 5
coins: 7
###############
coins: 7
books: 5
bottles: 4
pens: 3
cups: 2
bags: 1

从输出中我们可以看到,这次对按它们的值排序。

在 Python 教程的这一部分中,我们编写了有关 Python 字典的文章。

posted @ 2024-10-24 18:17  绝不原创的飞龙  阅读(0)  评论(0编辑  收藏  举报