ทำไมฉันถึงเห็น“ TypeError: ดัชนีสตริงต้องเป็นจำนวนเต็ม”


219

ฉันกำลังเล่นกับทั้งการเรียนรู้หลามและพยายามที่จะได้รับปัญหา Github ในรูปแบบที่อ่านได้ การใช้คำแนะนำเกี่ยวกับฉันจะแปลง JSON เป็น CSV ได้อย่างไร ฉันมากับสิ่งนี้:

import json
import csv

f=open('issues.json')
data = json.load(f)
f.close()

f=open("issues.csv","wb+")
csv_file=csv.writer(f)

csv_file.writerow(["gravatar_id","position","number","votes","created_at","comments","body","title","updated_at","html_url","user","labels","state"])

for item in data:
        csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])

โดยที่ "problems.json" เป็นไฟล์ json ที่มีปัญหา github ของฉัน เมื่อฉันพยายามที่จะเรียกใช้ฉันได้รับ

File "foo.py", line 14, in <module>
csv_file.writerow([item["gravatar_id"], item["position"], item["number"], item["votes"], item["created_at"], item["comments"], item["body"], item["title"], item["updated_at"], item["html_url"], item["user"], item["labels"], item["state"]])

TypeError: string indices must be integers

ฉันหายไปนี่อะไร "ดัชนีสตริง" คืออะไร ฉันแน่ใจว่าเมื่อฉันได้งานนี้ฉันจะมีปัญหาเพิ่มขึ้น แต่ตอนนี้ฉันแค่ชอบที่จะทำงาน!

เมื่อฉันปรับเปลี่ยนforคำสั่งเพื่อเพียงแค่

for item in data:
    print item

สิ่งที่ฉันได้รับคือ ... "ปัญหา" - ดังนั้นฉันจึงทำอะไรผิดไปมากกว่าปกติ นี่เป็นบิตของ json ของฉัน:

{"issues":[{"gravatar_id":"44230311a3dcd684b6c5f81bf2ec9f60","position":2.0,"number":263,"votes":0,"created_at":"2010/09/17 16:06:50 -0700","comments":11,"body":"Add missing paging (Older>>) links...

เมื่อฉันพิมพ์dataมันดูเหมือนว่าจะถูก munged อย่างผิดปกติ:

{u'issues': [{u'body': u'Add missing paging (Older>>) lin...

สิ่งที่คุณพลาดคือprint repr(data)หรือimport pprint; pprint.pprint(data)
จอห์นมาคิน

คำตอบ:


116

itemน่าจะเป็นสตริงในรหัสของคุณ ดัชนีสตริงเป็นดัชนีที่อยู่ในเครื่องหมายวงเล็บเหลี่ยมเช่นgravatar_id. ดังนั้นฉันจะตรวจสอบdataตัวแปรของคุณก่อนเพื่อดูว่าคุณได้รับอะไรบ้าง ฉันเดาว่าdataเป็นรายการของสตริง (หรืออย่างน้อยรายการที่มีอย่างน้อยหนึ่งสาย) ในขณะที่มันควรจะเป็นรายการของพจนานุกรม


158

ตัวแปรitemคือสตริง ดัชนีมีลักษณะดังนี้:

>>> mystring = 'helloworld'
>>> print mystring[0]
'h'

ตัวอย่างข้างต้นใช้0ดัชนีของสตริงเพื่ออ้างถึงอักขระตัวแรก

สตริงไม่สามารถมีดัชนีสตริง (เช่นพจนานุกรมสามารถ) ดังนั้นสิ่งนี้จะไม่ทำงาน:

>>> mystring = 'helloworld'
>>> print mystring['stringindex']
TypeError: string indices must be integers


36

TypeError สำหรับ Slice Notation str[a:b]

tl; dr:ใช้เครื่องหมายโคลอน :แทนเครื่องหมายจุลภาคในระหว่างสองดัชนีaและbในstr[a:b]


เมื่อทำงานกับสตริงและสัญกรณ์ชิ้น (การดำเนินการตามลำดับทั่วไป ) มันสามารถเกิดขึ้นได้ว่ามีการTypeErrorยกขึ้นชี้ให้เห็นว่าดัชนีจะต้องเป็นจำนวนเต็มแม้ว่าพวกเขาจะเห็นได้ชัดว่า

ตัวอย่าง

>>> my_string = "hello world"
>>> my_string[0,5]
TypeError: string indices must be integers

เห็นได้ชัดว่าเราผ่านจำนวนเต็มสองจำนวนสำหรับดัชนีไปยังสัญลักษณ์ชิ้นใช่มั้ย แล้วปัญหาคืออะไรที่นี่?

ข้อผิดพลาดนี้อาจทำให้หงุดหงิดมาก - โดยเฉพาะอย่างยิ่งในช่วงเริ่มต้นของการเรียนรู้ Python - เนื่องจากข้อความแสดงข้อผิดพลาดทำให้เข้าใจผิดเล็กน้อย

คำอธิบาย

เราส่งค่าtuple ของจำนวนเต็มสองจำนวน (0 และ 5) ไปยังเครื่องหมายสไลซ์เมื่อเราเรียกใช้my_string[0,5]เพราะ0,5(แม้ไม่มีวงเล็บ) จะประเมินค่าเป็น tuple แบบเดียวกับที่(0,5)ทำ

เครื่องหมายจุลภาค,นั้นเพียงพอสำหรับ Python ในการประเมินบางสิ่งเป็น tuple:

>>> my_variable = 0,
>>> type(my_variable)
<class 'tuple'>

ดังนั้นสิ่งที่เราทำที่นั่นคราวนี้อย่างชัดเจน:

>>> my_string = "hello world"
>>> my_tuple = 0, 5
>>> my_string[my_tuple]
TypeError: string indices must be integers

อย่างน้อยที่สุดข้อความแสดงข้อผิดพลาดก็สมเหตุสมผล

สารละลาย

เราจำเป็นต้องแทนที่เครื่องหมายจุลภาค ,ด้วยเครื่องหมายโคลอน :เพื่อแยกจำนวนเต็มสองจำนวนอย่างถูกต้อง:

>>> my_string = "hello world"
>>> my_string[0:5]
'hello'

ข้อความแสดงข้อผิดพลาดที่ชัดเจนและเป็นประโยชน์มากขึ้นอาจเป็นดังนี้:

TypeError: string indices must be integers (not tuple)

ข้อความแสดงข้อผิดพลาดที่ดีแสดงให้ผู้ใช้โดยตรงว่าพวกเขาทำอะไรผิดและจะเห็นได้ชัดว่าจะแก้ไขปัญหาได้อย่างไร

[ดังนั้นในครั้งต่อไปที่คุณพบว่าตัวเองรับผิดชอบในการเขียนข้อความอธิบายข้อผิดพลาดลองคิดถึงตัวอย่างนี้และเพิ่มเหตุผลหรือข้อมูลที่เป็นประโยชน์อื่น ๆ ลงในข้อความแสดงข้อผิดพลาดเพื่อให้คุณและคนอื่น ๆ เข้าใจว่าเกิดอะไรขึ้น]

บทเรียนที่ได้เรียนรู้

  • สัญกรณ์สไลซ์ใช้เครื่องหมายโคลอน:เพื่อแยกดัชนี (และช่วงสเต็ปเป็นต้นstr[from:to:step])
  • สิ่งอันดับถูกกำหนดโดยเครื่องหมายจุลภาค,(เช่นt = 1,)
  • เพิ่มข้อมูลลงในข้อความแสดงข้อผิดพลาดเพื่อให้ผู้ใช้เข้าใจสิ่งที่ผิดพลาด

ไชโยและมีความสุขในการเขียนโปรแกรม
winklerrr


[ฉันรู้ว่าคำถามนี้ได้ตอบไปแล้วและนี่ไม่ใช่คำถามที่ผู้เริ่มต้นเธรดถาม แต่ฉันมาที่นี่เพราะปัญหาข้างต้นซึ่งนำไปสู่ข้อความแสดงข้อผิดพลาดเดียวกัน อย่างน้อยฉันก็ต้องใช้เวลาพอสมควรกว่าจะได้เจอตัวพิมพ์เล็ก ๆ นั้น

ดังนั้นฉันหวังว่าสิ่งนี้จะช่วยให้คนอื่นที่สะดุดกับข้อผิดพลาดเดียวกันและช่วยพวกเขาในการค้นหาความผิดพลาดเล็ก ๆ น้อย ๆ ]


0

สิ่งนี้อาจเกิดขึ้นได้หากเครื่องหมายจุลภาคหายไป ฉันวิ่งเข้าไปหามันเมื่อฉันมีรายการทูเปิลสองตัวแต่ละอันประกอบด้วยสตริงในตำแหน่งแรกและรายการในลำดับที่สอง ฉันละเว้นเครื่องหมายจุลภาคหลังจากองค์ประกอบแรกของ tuple ในกรณีเดียวและล่ามคิดว่าฉันพยายามทำดัชนีองค์ประกอบแรก


0

ฉันมีปัญหาที่คล้ายกันกับ Pandas คุณต้องใช้ฟังก์ชั่น iterrows () เพื่อทำซ้ำผ่านเอกสารชุดข้อมูลPandas Pandas สำหรับ iterrows

data = pd.read_csv('foo.csv')
for index,item in data.iterrows():
    print('{} {}'.format(item["gravatar_id"], item["position"]))

โปรดทราบว่าคุณต้องจัดการดัชนีในชุดข้อมูลที่ส่งคืนโดยฟังก์ชัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.