Python中未知长度列表的变量赋值

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>

我正在抓取一个网站,以便在一个有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 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,我只是想