我想从2个列表中创建一个新列表。
一个列表(self.sequence)包含由QlineEdit()输入生成的所需索引。例如。当我在QlineEdit中输入0,1,2,6:11,0,23时,输出的列表看起来像这样(输入自动转换为unicode):
[u'0', u'1', u'2', u'6:11', u'0', u'23']
另一个列表(xcoord)只是一个常规的值列表。
新创建的列表应包含list(self.sequence)中的值,但仅包含list(coord)中的索引。 这是我的代码。现在给出一个TypeError:列表索引必须是整数,而不是列表
self.sequence_input = QtGui.QLineEdit()
def on_adjust(self):
self.sequence = self.sequence_input.text().split(',')
print self.sequence
self.xseq = self.xcoord[self.sequence]
self.yseq = self.ycoord[self.sequence]
print self.xse
我以前一直在寻找类似的问题,但我无法将答案应用到我的案例中。我对python很新。
答案 0 :(得分:0)
self.sequence
的值例如是[u'0', u'1', u'2', u'0', u'23']
(这里省略了切片,下面更多内容)意味着它是一个unicode字符串列表,要使用那里的值作为列表索引,你必须将值转换为int
,例如
int_sequeneces = [int(x) for x in self.sequence]
现在int_sequences
中的每个元素都是一个可用于索引列表的int
e.g。
first_index = int_sequences[0]
self.xcoord[first_index]
为了获得xcoord
和ycoord
的所有序列,您可以这样做:
self.xseq = [self.xcoord[index] for index in int_sequences]
self.yseq = [self.ycoord[index] for index in int_sequences]
def expand_slice(x):
"""
Converts '6:11' to [6, 7, 8, 9, 10]
"""
a, b = x.split(':')
return list(xrange(int(a), int(b)))
def parse_seq(x):
"""
Deals with both int and slices in a uniform way,
by returning a list of indices
"""
return expand_slice(x) if ':' in x else [int(x)]
对于要用作索引列表的列表,它必须是平的,其中每个元素都是有效的索引,例如一个int,如[1, 2, 3, 4, 5]
而不是[1, [2, 3, 4], 5]
。我们可以使用下面的代码将其展平为itertools.chain()
itertools.chain(*[parse_seq(x) for x in index_and_slices])
此行为类似于列表,但您可以明确转换它以显示list()
In [28]: import itertools
In [29]: def expand_slice(x): a, b = x.split(':'); return list(xrange(int(a), int(b)))
In [30]: def parse_seq(x): return expand_slice(x) if ':' in x else [int(x)]
In [31]: index_and_slices = [u'0', u'1', u'2', u'6:11', u'0', u'23']
In [32]: [parse_seq(x) for x in index_and_slices]
Out[33]: [[0], [1], [2], [6, 7, 8, 9, 10], [0], [23]]
In [32]: list(itertools.chain(*[parse_seq(x) for x in index_and_slices]))
Out[32]: [0, 1, 2, 6, 7, 8, 9, 10, 0, 23]
如果您6:11
表示[6, 7, 8, 9, 10, 11]
,则只需相应修改expand_slice()
功能,例如使用xrange(int(a), int(b) + 1)
,但我放在这里的行为是Python传统中的默认行为
我没有对您的输入进行验证,但是您可以捕获异常,然后将它们报告给界面(在Python中,要求宽恕通常比要求许可更优雅)
答案 1 :(得分:0)
您无法使用字符串对列表进行索引或切片。您必须将输入从unicode解析为int。问题是你还有切片6:11
。
解决方案可能是这样的:
self.sequence = self.sequence_input.text().split(',')
print self.sequence
for obj in self.sequence.split(':'):
to_add = obj[0] if len(obj) < 2 else slice(obj[0], obj[1])
self.xseq.append(self.xcoord[to_add])
self.yseq.append(self.ycoord[to_add])
现在您可能有一个列表列表,因为切片返回一个列表。然后,您可以展平self.xseq
和self.yseq
。
import itertools
self.xseq = itertools.chain(*self.xseq)
self.yseq = itertools.chain(*self.yseq)
答案 2 :(得分:0)
您可以通过提供索引来访问列表,该索引是您要采用的数据的位置而不是列表:
for a in sel.sequence:
if ":" in s:
s=s.split(":")
for ss in range(int(s[0]),int(s[1])):
self.xseq.append(self.xcoord[ss])
else:
self.yseq.append(self.ycoord[int(s)])
<强>即。)强>
a=["1","2","3"]
b=[2,4,5,7]
b[a]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-68-9f1bfc533672> in <module>()
----> 1 b[a]
TypeError: list indices must be integers, not list
访问的一种方法是遍历列表:
a=["1","2:3","3"]
b=[2,4,5,7]
for s in a:
if ":" in s:
s=s.split(":")
for ss in range(int(s[0]),int(s[1])+1):
print b[ss]
else:
print b[int(s)]
4
5
7
7
答案 3 :(得分:0)
这是一种稍微不同的方法:
xcoord = [1,5,10,15,5,3,5,20,80,70,1,5,10,15,5,3,5,20,80,70,1,5,10,15,5,3,5,20,80,70]
ycoord = [0,2,7,3,8,50,4,6,3,0,2,7,3,8,50,4,6,3,0,2,7,3,8,50,4,6,3,0]
sequences = [u'0', u'1', u'2', u'6:11', u'0', u'23']
xseq = []
yseq = []
for sequence in sequences:
try:
exec("xseq.append(xcoord[%s])" % sequence)
exec("yseq.append(ycoord[%s])" % sequence)
except IndexError:
print "Slice sequence %s is out of range" % sequence
break
print xseq
print yseq
这为我的样本数据提供了以下输出:
[1, 5, 10, [5, 20, 80, 70, 1], 1, 15]
[0, 2, 7, [4, 6, 3, 0, 2], 0, 50]
注意,您需要确保您的序列被清理为仅包含切片。