Python根据先前的值修改列表值的列表

时间:2018-12-20 16:31:55

标签: python python-3.x

在我的项目中,我有一个像这样的列表:

varlist = [['Variables', ''], ['bs_${FORM_URL}', 'SC'], ['${FORM_URL}', 'http://www.example.com'], ['bs_${NUM_RAND}', 'RN'], ['${NUM_RAND}', '0-200'], ['bs_${TEXT}', 'SC'], ['${TEXT}', 'mytest']]

我必须检查是否有一个具有RN值的数据,如果发现了此值,请根据下一个列表值使用随机值更改下一个嵌套列表值。 在我的示例中,有一个带有RN的列表(['bs _ $ {NUM_RAND}','RN']),好吧,我必须将其删除并更改下一个列表值(['$ {NUM_RAND}', '0-200'])创建一个介于0到200之间的int随机数。 我这样尝试:

p_oper = 'SC'        
for li in varlist:
    if li[0][0:3] == 'bs_':
        p_oper = li[1]
        varlist.remove(li)
    else:
        if p_oper == 'RN':
            num1 = int(li[1].split('-')[0].strip())
            num2 = int(li[1].split('-')[1].strip())
            li[1] = str(int(random.randint(num1, num2)))

在函数结尾处,结果列表应如下所示:

[['Variables', ''], ['${FORM_URL}', 'http://www.example.com'], ['${NUM_RAND}', '42'], ['${TEXT}', 'mytext']]

但这不起作用。 任何人都对我如何以这种方式操纵列表清单有任何想法吗?

3 个答案:

答案 0 :(得分:2)

之所以发生这种情况,是因为一旦删除列表中的项目,索引就会更改。一个简单的解决方法是维护原始列表的状态,并对列表的副本进行修改,如下所示:

import random

p_oper = 'SC'
new_varlist = varlist[:]  # Making a copy of the original list
for li in varlist:
    if li[0][0:3] == 'bs_':
        p_oper = li[1]
        new_varlist.remove(li)  # Removing the item in the new list only
    else:
        if p_oper == 'RN':
            num1 = int(li[1].split('-')[0])
            num2 = int(li[1].split('-')[1])
            li[1] = str(int(random.randint(num1, num2)))

现在您有了有效的代码,并且可以访问两个列表,这些列表可以准确打印出您要查找的内容:

>>> print(varlist)

[['Variables', ''], ['bs_${FORM_URL}', 'SC'], ['${FORM_URL}', 'http://www.example.com'], ['bs_${NUM_RAND}', 'RN'], ['${NUM_RAND}', '90'], ['bs_${TEXT}', 'SC'], ['${TEXT}', 'mytest']]

>>> print(new_varlist)

[['Variables', ''], ['${FORM_URL}', 'http://www.example.com'], ['${NUM_RAND}', '90'], ['${TEXT}', 'mytest']]

如果您想保持原始列表不变,而不修改列表['${NUM_RAND}', '0-200'],则还可以制作一个深层副本。如果您需要此功能,也可以轻松完成此操作:

from copy import deepcopy

p_oper = 'SC'
original_varlist = deepcopy(varlist)

# ...

答案 1 :(得分:2)

您可能会选择删除“ bs”子列表并创建一个新的子列表,而不是删除它们:

varlist[0]] + [[v[0], str(random.randint(*map(int, v[1].split('-'))))] if bs[1] == 'RN' else v for bs, v in zip(varlist[1::2], varlist[2::2])]

# Result: 
[['Variables', ''], ['${FORM_URL}', 'http://www.example.com'], ['${NUM_RAND}', '4'], ['${TEXT}', 'mytest']]

基本上可以将这一衬里改写成这样:

l = [varlist[0]]
for bs, v in zip(varlist[1::2], varlist[2::2]):
    if bs[1] == 'RN':
        n, m = map(int, v[1].split('-'))
        l.append([v[0], str(random.randint(n, m))])
    else:
        l.append(v)

通过zip函数,您可以交叉原始varlist的参考切片,同时有效地删除“ bs”子列表。

答案 2 :(得分:1)

假定列表的子列表中始终有两个项目;可以这样:

import random

varlist = [['Variables', ''], ['bs_${FORM_URL}', 'SC'], ['${FORM_URL}', 'http://www.example.com'], ['bs_${NUM_RAND}', 'RN'], ['${NUM_RAND}', '0-200'], ['bs_${TEXT}', 'SC'], ['${TEXT}', 'mytest']]

for i,j  in enumerate(varlist):
    if 'RN' in j:
        varlist.remove(varlist[i])
        varlist[i][1] = random.randint(0, 200)

print(varlist)

Output: [['Variables', ''], ['bs_${FORM_URL}', 'SC'], ['${FORM_URL}', 'http://www.example.com'], ['${NUM_RAND}', 147], ['bs_${TEXT}', 'SC'], ['${TEXT}', 'mytest']]