我有一个可以是任何深度或长度的列表。我的意思是说我可以有一个像这样的列表:
lst = [1,2,3]
或者:
lst = [[2,233],[[[4,5],[66.33]],[[24,88.65,103,2200.0],[-44.2,-8,5]]], [[[[[[[[5]]]]]]]]]
我想做的是随机修改列表中这些数值中的任何一个。我知道我可以通过将列表转换为字符串来做一些狡猾的事情,但是如果有一种标准的方法,那么对此的答案将是可取的!
编辑:
对于那些不知道的人,您不能简单地随机选择这些值中的任何一个并对其进行修改(例如,向其添加1),因为该列表可以嵌套。这是我尝试获取的输入和输出的示例:
lst = [[2,233],[[[4,5],[66.33]],[[24,88.65,103,2200.0],[-44.2,-8,5]]], [[[[[[[[5]]]]]]]]]
lst = modify(lst,4) # Where 4 is the amount to add to a random number in the list
>lst: [[2,233],[[[4,9],[66.33]],[[24,88.65,103,2200.0],[-44.2,-8,5]]], [[[[[[[[5]]]]]]]]]
# the fourth number to appear left-to-right in the list 5 has had 4 added to it, ultimately resulting in 9
# this number was randomly selected
再次运行相同的代码,lst
现在已更新:
lst = modify(lst,-2)
>lst: [[2,233],[[[4,9],[66.33]],[[24,86.65,103,2200.0],[-44.2,-8,5]]], [[[[[[[[5]]]]]]]]]
# The seventh number 88.65 has had 2 subtracted from it, to ultimately equal 86.65
答案 0 :(得分:2)
第一个问题是无论嵌套的深度如何,都按顺序遍历列表。这是一个生成器,它只返回该值(受this answer启发):
python db_copy_table.py "host=192.168.1.1 port=5432 user=admin password=admin dbname=mydb" "host=localhost port=5432 user=admin password=admin dbname=mydb" alarmrules -w "WHERE id=19" -v
Source number of rows = 2
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister1',true,false);
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister2',true,false);
可以这样使用:
import functools
import operator
def iter_nested_list(input_list):
# build index of first level elements
index_list_to_check = [(i, ) for i in range(len(input_list))]
while len(index_list_to_check) > 0:
current_index = index_list_to_check.pop(0)
# get the element
elem = functools.reduce(operator.getitem, current_index, input_list)
if isinstance(elem, list):
for i in range(len(elem)):
# this is a list, so we need to check one level deeper
index_list_to_check.append(current_index + (i, ))
else:
# this is not a list, so we yield the index
yield current_index
要从列表中获取单个元素,我们可以使用产生的索引:
>>> list_1 = [[2,233],[[[4,5],[66.33]],[[24,88.65,103,2200.0],[-44.2,-8,5]]],[[[[[[[[5]]]]]]]]]
>>> iter_nested_list(list_1)
<generator object iter_nested_list at 0x7fdbbc29d990>
>>> list(iter_nested_list(list_1))
[(0, 0), (0, 1), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 0, 2), (1, 1, 0, 3), (1, 1, 1, 0), (1, 1, 1, 1), (1, 1, 1, 2), (2, 0, 0, 0, 0, 0, 0, 0, 0)]
现在,要修改元素:
>>> index_list = list(iter_nested_list(list_1))
>>> index = index_list[1]
>>> index
(0, 1)
>>> functools.reduce(operator.getitem, index, input_list)
233
在这里起作用:
def modify(input_list, value_to_add):
index_list = list(iter_nested_list(list_1))
index = random.choice(index_list)
index_base = index[:-1] # list of all elements from 'index' excluding the last one
index_elem = index[-1] # single element, the last of the list 'index'
# get list that holds the value we randomly selected
sub_list = functools.reduce(operator.getitem, index_base, input_list)
# modify value
sub_list[index_elem] += value_to_add