MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python创建数值列表的方法

2022-06-104.1k 阅读

使用range()函数创建数值列表

在Python中,range()函数是创建数值列表的常用工具之一。range()函数能够生成一系列连续的整数,这对于需要创建有序数值序列的场景非常有用。

range()函数的基本用法

range()函数最基本的形式为range(stop),其中stop是一个整数,它表示生成的整数序列的结束值(但不包含该值)。例如:

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

上述代码会打印出04这5个整数。因为range(5)生成的序列是从0开始,到4结束,不包含5

range()函数带起始值的用法

range()函数还可以接受两个参数,形式为range(start, stop),其中start是起始值(包含该值),stop是结束值(不包含该值)。例如:

for num in range(2, 7):
    print(num)

这段代码会打印出26这5个整数,因为range(2, 7)生成的序列从2开始,到6结束。

range()函数带步长的用法

range()函数还支持第三个参数,用于指定步长,形式为range(start, stop, step)step表示相邻两个数之间的差值。例如:

for num in range(1, 10, 2):
    print(num)

上述代码会打印出13579,因为range(1, 10, 2)生成的序列从1开始,每次增加2,直到小于10为止。

range()结果转换为列表

range()函数返回的是一个可迭代对象,而不是列表。如果需要得到一个列表,可以使用list()函数将其转换。例如:

num_list = list(range(5))
print(num_list)

运行上述代码,会输出[0, 1, 2, 3, 4],通过list()函数将range(5)生成的可迭代对象转换为了列表。

使用列表推导式创建数值列表

列表推导式是Python中一种简洁而强大的创建列表的方式,对于创建数值列表同样非常有效。

基本的列表推导式创建数值列表

列表推导式的基本形式为[expression for item in iterable]。对于创建数值列表,我们可以这样使用:

squares = [num ** 2 for num in range(1, 6)]
print(squares)

上述代码使用列表推导式创建了一个包含15的平方值的列表。num ** 2是表达式,num是迭代变量,range(1, 6)是可迭代对象。

带条件的列表推导式创建数值列表

列表推导式还可以包含条件语句,形式为[expression for item in iterable if condition]。例如,我们只想要偶数的平方:

even_squares = [num ** 2 for num in range(1, 6) if num % 2 == 0]
print(even_squares)

在这段代码中,if num % 2 == 0是条件语句,只有当num是偶数时,才会计算其平方并添加到列表中。所以输出结果是[4, 16],分别是24的平方。

嵌套的列表推导式创建数值列表

列表推导式可以嵌套,这在一些复杂的数值列表创建场景中很有用。例如,我们想要创建一个矩阵(二维列表),其中每个元素是其行号和列号的乘积:

matrix = [[i * j for j in range(1, 4)] for i in range(1, 3)]
print(matrix)

这里外层的for i in range(1, 3)控制行,内层的for j in range(1, 4)控制列。每个元素i * j是行号i和列号j的乘积。输出结果是[[1, 2, 3], [2, 4, 6]],表示一个2行3列的矩阵。

使用numpy库创建数值列表(数组)

numpy是Python中用于数值计算的重要库,它提供了高效的数组操作。虽然numpy中的数组和Python原生列表有所不同,但在很多数值计算场景中,numpy数组更具优势。

安装numpy

如果尚未安装numpy库,可以使用pip install numpy命令进行安装。

使用numpy.arange()创建数值数组

numpy.arange()函数类似于Python内置的range()函数,但它返回的是numpy数组。其基本形式为numpy.arange(stop),也可以接受startstep参数,形式为numpy.arange(start, stop, step)。例如:

import numpy as np
arr = np.arange(5)
print(arr)

上述代码导入numpy库并将其简称为np,然后使用np.arange(5)创建了一个包含04numpy数组。输出结果类似[0 1 2 3 4],和Python列表有所不同,numpy数组的元素之间没有逗号分隔,并且有特定的打印格式。

使用numpy.linspace()创建数值数组

numpy.linspace()函数用于创建一个在指定范围内均匀分布的数值数组。其形式为numpy.linspace(start, stop, num=50, endpoint=True),其中start是起始值,stop是结束值,num表示生成的元素数量,endpoint表示是否包含结束值。例如:

import numpy as np
arr = np.linspace(0, 1, 5)
print(arr)

这段代码创建了一个从01(包含1,因为endpoint=True)均匀分布的包含5个元素的numpy数组。输出结果可能是[0. 0.25 0.5 0.75 1. ]

使用numpy.zeros()numpy.ones()创建特定数值的数组

numpy.zeros()函数用于创建一个全零的numpy数组,numpy.ones()函数用于创建一个全一的numpy数组。它们的基本形式为numpy.zeros(shape)numpy.ones(shape),其中shape可以是一个整数表示一维数组的长度,也可以是一个元组表示多维数组的形状。例如:

import numpy as np
zero_arr = np.zeros(3)
one_arr = np.ones((2, 3))
print(zero_arr)
print(one_arr)

上述代码创建了一个长度为3的全零一维数组zero_arr,以及一个2行3列的全一二维数组one_arr。输出结果中,zero_arr类似[0. 0. 0.]one_arr类似[[1. 1. 1.], [1. 1. 1.]]

使用pandas库创建数值列表(序列)

pandas是Python中用于数据处理和分析的重要库,它的Series数据结构可以看作是一种特殊的数值列表。

安装pandas

如果尚未安装pandas库,可以使用pip install pandas命令进行安装。

使用pandas.Series()创建数值序列

pandas.Series()函数可以从多种数据类型创建数值序列。例如,从Python列表创建:

import pandas as pd
data = [1, 2, 3, 4, 5]
series = pd.Series(data)
print(series)

上述代码导入pandas库并将其简称为pd,然后使用pd.Series()函数将Python列表data转换为pandasSeries对象。输出结果会包含索引和对应的值,例如:

0    1
1    2
2    3
3    4
4    5
dtype: int64

这里的索引默认从0开始,dtype表示数据类型为int64

使用pandas.Series()range()创建数值序列

我们也可以直接从range()对象创建Series。例如:

import pandas as pd
series = pd.Series(range(1, 6))
print(series)

这段代码创建了一个包含15Series对象,输出结果类似:

0    1
1    2
2    3
3    4
4    5
dtype: int64

使用pandas.Series()创建具有特定索引的数值序列

pandas.Series()函数还可以接受一个index参数来指定自定义的索引。例如:

import pandas as pd
data = [10, 20, 30]
index = ['a', 'b', 'c']
series = pd.Series(data, index=index)
print(series)

在这段代码中,我们创建了一个包含102030Series对象,并使用['a', 'b', 'c']作为索引。输出结果为:

a    10
b    20
c    30
dtype: int64

创建数值列表时的性能考量

在选择创建数值列表的方法时,性能是一个重要的考量因素。不同的方法在时间复杂度和空间复杂度上可能有所不同。

原生range()和列表推导式的性能

对于简单的数值列表创建,原生的range()函数和列表推导式在性能上表现良好。range()函数本身并不占用大量内存,因为它是一个可迭代对象,只有在迭代时才生成具体的值。列表推导式在创建列表时,会一次性生成所有值并占用相应的内存。但对于较小规模的列表,这种内存占用的差异并不明显。

例如,我们可以使用timeit模块来测试它们的性能。下面的代码测试了使用range()并转换为列表和使用列表推导式创建包含1000个元素的列表的时间:

import timeit

range_time = timeit.timeit('list(range(1000))', number=1000)
list_comp_time = timeit.timeit('[num for num in range(1000)]', number=1000)

print(f'Using range(): {range_time}')
print(f'Using list comprehension: {list_comp_time}')

在大多数情况下,使用range()并转换为列表会稍微快一些,因为它的操作相对简单,只是将可迭代对象转换为列表。而列表推导式还需要进行表达式的计算(虽然这里只是简单的num)。

numpy数组的性能优势

numpy数组在数值计算方面具有显著的性能优势。numpy的底层实现使用了高效的C语言代码,这使得对数组的操作非常快速。例如,对numpy数组进行数学运算时,numpy会对整个数组进行向量化操作,而不是像Python原生列表那样逐个元素进行操作。

我们可以通过一个简单的例子来对比。假设我们要对一个包含100000个元素的列表或numpy数组中的每个元素加1:

import timeit
import numpy as np

# 创建Python列表
python_list = list(range(100000))
# 创建numpy数组
numpy_arr = np.arange(100000)

python_list_time = timeit.timeit('''
new_list = []
for num in python_list:
    new_list.append(num + 1)
''', globals=globals(), number=100)

numpy_arr_time = timeit.timeit('numpy_arr + 1', globals=globals(), number=100)

print(f'Using Python list: {python_list_time}')
print(f'Using numpy array: {numpy_arr_time}')

可以看到,使用numpy数组进行操作的时间远远小于使用Python原生列表的时间。这是因为numpy数组的向量化操作避免了Python的循环开销,从而提高了效率。

pandas.Series的性能

pandas.Series在数据处理和分析场景中具有很好的性能。它基于numpy数组进行了进一步的封装,提供了更多的数据处理功能。例如,Series对象支持灵活的索引和对齐操作,并且在数据筛选、统计计算等方面也有高效的实现。

然而,在单纯创建数值序列方面,如果只是简单的数值列表创建,pandas.Series的性能可能不如numpy数组和Python原生的列表创建方式。因为Series对象在创建时需要额外处理索引等信息,增加了一定的开销。但当涉及到复杂的数据处理任务时,pandas.Series的优势就会体现出来。

不同场景下选择合适的创建方法

在实际编程中,需要根据具体的场景来选择合适的创建数值列表的方法。

简单数值序列场景

如果只是需要创建一个简单的、规模较小的数值序列,并且后续不需要进行复杂的数值计算,使用Python原生的range()函数并转换为列表或者使用列表推导式就足够了。例如,在循环中作为索引使用,或者简单地存储一些有序的整数。

# 使用range()并转换为列表
index_list = list(range(10))
# 使用列表推导式
square_list = [num ** 2 for num in range(5)]

数值计算场景

当涉及到大量的数值计算,如数学运算、统计分析等,numpy数组是首选。numpy提供了丰富的数学函数和高效的向量化操作,能够大大提高计算效率。

import numpy as np
arr = np.arange(100000)
result = np.sin(arr)

数据处理和分析场景

在数据处理和分析领域,pandas.Series是常用的数据结构。它不仅支持数值计算,还提供了强大的数据处理功能,如数据筛选、分组、排序等。例如,在处理带有标签的数据时,pandas.Series的索引功能非常有用。

import pandas as pd
data = [10, 20, 30]
index = ['a', 'b', 'c']
series = pd.Series(data, index=index)
filtered_series = series[series > 15]

多维数据场景

对于多维数据,numpy数组和pandasDataFrame(可以看作是二维的Series)都能很好地胜任。numpy数组适用于纯数值的多维数据,而pandasDataFrame更适合带有列标签和行索引的结构化数据。

import numpy as np
import pandas as pd

# 创建numpy二维数组
numpy_matrix = np.array([[1, 2, 3], [4, 5, 6]])

# 创建pandas DataFrame
data = {'col1': [1, 2], 'col2': [3, 4]}
df = pd.DataFrame(data)

在不同场景下选择合适的创建数值列表(或类似数据结构)的方法,能够提高代码的效率和可读性,使程序更加符合实际需求。同时,理解不同方法的底层原理和性能特点,有助于我们在编程过程中做出更明智的决策。无论是简单的循环索引,还是复杂的数据分析任务,通过合理运用这些方法,都能让我们的Python编程更加得心应手。在实际项目中,可能还需要考虑与其他库的兼容性、数据的存储和传输等因素,综合权衡后选择最适合的方案。例如,如果数据需要与数据库进行交互,pandasDataFrame可能更容易与数据库的表结构进行映射和操作;而如果是进行科学计算,numpy数组的高效性则更为关键。通过不断实践和积累经验,我们能够更好地掌握这些创建数值列表的方法,并在各种编程场景中灵活运用。