从包含一个元组的列表中提取值
我正在使用Python的Google App Engine。
我搞不懂为什么我不能用[index]
从我的元组中提取值。从日志中我看到我的leveloneAdd
变量里确实有值,比如说('english'
, 'subject'
),但是当我在循环这个元组的时候,我的tag
和htype
变量却是空的,我本来期待tag = 'english'
和htype = 'subject'
。
有没有人能帮我想想原因?
for each in leveloneAdd:
tag = each[0]
htype = each[1]
q1 = Level_1_Headings.all().filter("name1 =",tag).filter("heading_type =",htype).get()
所以我按照Martijn的建议在日志中做了repr,这里是我的日志:感谢大家的意见!我很喜欢这个论坛——这是我根据Martijn的建议得到的日志——我觉得它把整个东西当成了一个字符串来处理——
INFO 2013-01-14 19:28:17,030 main.py:291] each is ('math', 'subject')
INFO 2013-01-14 19:28:17,030 main.py:292] u"('math', 'subject')"
INFO 2013-01-14 19:28:17,030 main.py:294] tag is (
INFO 2013-01-14 19:28:17,030 main.py:296] heading type is '
看起来这个字符串被当作字符串来看待?我该怎么把它转换成真正的元组呢?这是我原本应该创建元组的代码(然后它传到客户端,再返回,正如日志所示)。
for x in h1: listone.append((str(x.name1),str(x.heading_type)))
上面的值是在一个输入选择下拉框中,然后从服务器端的Python中,我通过
leveloneAdd = (self.request.get_all("list_uno[]"))来获取这些值。
抱歉如果这些问题看起来很基础,我是个初学者,想要变得更好!!
3 个回答
试试这个:
for (tag, htype) in leveloneAdd:
# stuff
如果它不是一个元组,你会遇到类似“值太多,无法解包”的错误。
我之前理解错了提问者的问题。
当我遇到这样的麻烦时,我通常会尝试这样做:
for thing in list:
try:
(tag, htype) = thing
except:
import pdb
pdb.set_trace()
这样你就可以打开调试工具,看看'东西'是不是你想的那样。
根据提问者的说法,'东西'其实不是一个元组,而是一个unicode字符串。要解决这个问题,可以先把它转换成字符串,然后再分割这个字符串。代码如下:
thing = u'(a,b)'
[tag, htype] = str(thing).lstrip('(').rstrip(')').split(',')
这段代码假设你总是期待得到一个包含两个元素的元组。
F.C.说的没错。
我对单个元素和元组的问题有点困惑。如果基本问题只是检测你在leveloneAdd
中是有简单值还是元组作为元素,也许你可以考虑把listoneAdd
作为一个元组的列表,即使你添加的东西是单个元素。这样,当你从列表中取出一个元素时,你总是知道可以对它进行索引:
listoneAdd = [('one',), ('foot',), ('three', 'pigs')]
for element in listoneAdd:
print "element is " + str(element)
for i in range(0,len(element)):
print " do something with value " + element[i]`
这样就会得到:
element is ('one',)
do something with value one
element is ('foot',)
do something with value foot
element is ('three', 'pigs')
do something with value three
do something with value pigs`
如果 leveloneAdd == ('english', 'subject')
,那么它不是一个元组列表,而只是一个元组,所以在每次循环中,each
的值会是一个字符串。
如果 leveloneAdd == [('english', 'subject')]
,也就是一个里面有元组的列表,你的代码就能正常工作。
如果可以的话,最好的办法是修正代码,让 leveloneAdd 始终是一个元组列表。如果做不到这一点,那就得在 leveloneAdd 是一个包含两个字符串的元组时,把它转换成列表。要小心,测试所有输入,因为处理这种转换时很容易出错。
在 文档 中提到 get_all
应该返回一个列表,可能只有在有多个参数时才返回列表。如果是这样的话,你可以在值是字符串时把它转换成列表:
if isinstance(leveloneAdd, basestring):
leveloneAdd = [leveloneAdd]
之后只需用 ',' 来分割 leveloneAdd 的值。
同时调整你的 JavaScript,以避免出现多余的字符,比如 "(" 和 "'"。