Python中未知长度列表的变量赋值
我正在抓取一个网站,以便在一个有3列的数据库中存储数据。我正在抓取的网站部分看起来像下面三个例子中的一个Python中未知长度列表的变量赋值,python,list,variable-assignment,Python,List,Variable Assignment,我正在抓取一个网站,以便在一个有3列的数据库中存储数据。我正在抓取的网站部分看起来像下面三个例子中的一个 # Example 1: <div> <a href="sample1">text1</a> </div> # Example 2: <div> <a href="sample1">text1</a> <a href="sample2">text2</a> </div>
# Example 1:
<div>
<a href="sample1">text1</a>
</div>
# Example 2:
<div>
<a href="sample1">text1</a>
<a href="sample2">text2</a>
</div>
# Example 3:
<div>
<a href="sample1">text1</a>
<a href="sample2">text2</a>
<a href="sample3">text3</a>
</div>
编辑:
我尝试在数据库中包含三个字段的原因是,我希望能够根据这些不同的变量进行过滤。var1是最精确的标签,var2稍微精确一些,而var3在高水平上是精确的。把它想象成衣服。。。var1可以是灰色宽松裤,var2可以是商务宽松裤,var3可以是裤子。您可以使用一些简单的列表乘法:
# use a constant at the top of your script in case the number of columns
# change in the future
COLUMNS = 3
# ... other code ...
all = [s.text for s in soup.find_all('a')]
all.extend(['']*(COLUMNS-len(all))) # append 1 empty string for each missing text field
var1, var2, var3 = all
但正如大卫·泽门斯(David Zemens)在评论中提到的,必须有更好的方法来做到这一点。如果没有看到使用文本变量的代码,我无法给出任何具体的建议,但是您应该认真地重新考虑您的设计。即使像我建议的那样使用常量,拥有var1,var2,var3=all
仍然会使将来维护和修改此脚本变得困难
根据你的编辑,我建议你改用字典。这将允许您按名称引用特定数据,就像引用变量一样,但保留了列表的灵活性,而不是限制您硬编码的变量数量 例如:
all = [s.text for s in soup.find_all('a')]
d = {}
for i, field in enumerate(all):
d['var{}'.format(i)] = field
# later in your code that consumes this dictionary...
try:
foo(d['var1']) # function to do something with the scraped string corresponding
# to var1
except KeyError:
# do something else or pass when the expected data doesn't exist
如果all
是['a','b']
,则此代码生成以下内容:
{'var1':'b','var0':'a'}
变量赋值实际上只是一个映射——代码知道变量名,并且可以查找相应的值。字典允许您的代码动态构建映射,而无需硬编码。现在我们已经构建了一个字典,其中varX
变量是动态构造的。如果您决定添加另一列,则根本不必更改此代码。您只需添加将使用var4
的代码,并准备在字典中不存在var4
时捕获异常。不再添加空字符串-您的代码已准备好处理其查找的数据不存在的情况
注:
enumerate()
函数迭代一个iterable对象,并为您增加一个计数器。在我的代码中,i
是计数器(因此我们可以构造“var1”、“var2”…字符串),而字段
是列表中的每个项目您可以使用一些简单的列表乘法:
# use a constant at the top of your script in case the number of columns
# change in the future
COLUMNS = 3
# ... other code ...
all = [s.text for s in soup.find_all('a')]
all.extend(['']*(COLUMNS-len(all))) # append 1 empty string for each missing text field
var1, var2, var3 = all
但正如大卫·泽门斯(David Zemens)在评论中提到的,必须有更好的方法来做到这一点。如果没有看到使用文本变量的代码,我无法给出任何具体的建议,但是您应该认真地重新考虑您的设计。即使像我建议的那样使用常量,拥有var1,var2,var3=all
仍然会使将来维护和修改此脚本变得困难
根据你的编辑,我建议你改用字典。这将允许您按名称引用特定数据,就像引用变量一样,但保留了列表的灵活性,而不是限制您硬编码的变量数量 例如:
all = [s.text for s in soup.find_all('a')]
d = {}
for i, field in enumerate(all):
d['var{}'.format(i)] = field
# later in your code that consumes this dictionary...
try:
foo(d['var1']) # function to do something with the scraped string corresponding
# to var1
except KeyError:
# do something else or pass when the expected data doesn't exist
如果all
是['a','b']
,则此代码生成以下内容:
{'var1':'b','var0':'a'}
变量赋值实际上只是一个映射——代码知道变量名,并且可以查找相应的值。字典允许您的代码动态构建映射,而无需硬编码。现在我们已经构建了一个字典,其中varX
变量是动态构造的。如果您决定添加另一列,则根本不必更改此代码。您只需添加将使用var4
的代码,并准备在字典中不存在var4
时捕获异常。不再添加空字符串-您的代码已准备好处理其查找的数据不存在的情况
注:
enumerate()
函数迭代一个iterable对象,并为您增加一个计数器。在我的代码中,i
是计数器(因此我们可以构造“var1”、“var2”…字符串),而字段
是列表中的每个项目all = soup.find_all('a')
var1 = all[0].text if len(all) > 0 else ""
var2 = all[1].text if len(all) > 1 else ""
var3 = all[2].text if len(all) > 2 else ""
条件表达式x if y else z
(通常称为三元运算符)使代码简单易读。不过它不会赢得任何设计奖项。那么:
all = soup.find_all('a')
var1 = all[0].text if len(all) > 0 else ""
var2 = all[1].text if len(all) > 1 else ""
var3 = all[2].text if len(all) > 2 else ""
条件表达式
x if y else z
(通常称为三元运算符)使代码简单易读。不过,它不会赢得任何设计奖项。你的第二次尝试可能更像是蟒蛇。当然,您事先不知道.find_all
的结果是否是长度==3(或更多或更少)的列表。因此,您应该使用try/except或其他逻辑来控制结果写入数据库的方式/时间
# create a dictionary of your database column names:
dbColumns = {0:'column1', 1:'column2', 2:'column3'}
# get all the results; there might be 0 or 3 or any number really,
# we'll deal with that later
results = [s.text if s.text else "" for s in soup.find_all('a')]
# iterate the items in the list, and put in corresponding DB
for col in range(len(results)):
# use the dbColumns dict to insert to the desired column
query = "Insert INTO [db_name].[" + dbColumns[col] + "]"
query += "VALUES '" + results[i] + '"
"""
db.insert(query) # assumes a db object that has an "insert" function; modify as needed
"""
这种方法的要点是,从技术上讲,这个问题似乎并不需要对三个对象(var1、var2、var3)进行硬编码并尝试分配给它们。相反,只需返回
find_all
的结果,并根据结果列表中的索引对其进行处理。您的第二次尝试可能更像python。当然,您事先不知道.find_all
的结果是否是长度==3(或更多或更少)的列表。因此,您应该使用try/except或其他逻辑来控制结果写入数据库的方式/时间
# create a dictionary of your database column names:
dbColumns = {0:'column1', 1:'column2', 2:'column3'}
# get all the results; there might be 0 or 3 or any number really,
# we'll deal with that later
results = [s.text if s.text else "" for s in soup.find_all('a')]
# iterate the items in the list, and put in corresponding DB
for col in range(len(results)):
# use the dbColumns dict to insert to the desired column
query = "Insert INTO [db_name].[" + dbColumns[col] + "]"
query += "VALUES '" + results[i] + '"
"""
db.insert(query) # assumes a db object that has an "insert" function; modify as needed
"""
这种方法的要点是,从技术上讲,这个问题似乎并不需要对三个对象(var1、var2、var3)进行硬编码并尝试分配给它们。相反,只需返回find_all
的结果,并根据结果列表中的索引对其进行处理。您可以尝试此方法
#if list1 has uncertain number of values and you want to give them each variable
#create random list2 with max number of possible veriables
list2 = ['var1', 'var2', 'var3', 'var4' , . . . ]
for li1, li2 in zip(list1, list2):
globals()[li2] = li1
print(li2)
我不擅长python,我只是想