Mengapa saya melihat "TypeError: indeks string harus bilangan bulat"?

219

Saya bermain dengan kedua belajar python dan mencoba untuk mendapatkan masalah github ke dalam bentuk yang mudah dibaca. Menggunakan saran tentang Bagaimana saya bisa mengkonversi JSON ke CSV? Saya datang dengan ini:

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"]])

Di mana "issues.json" adalah file json yang berisi masalah github saya. Ketika saya mencoba menjalankannya, saya mengerti

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

Apa yang kulewatkan di sini? Manakah "indeks string" itu? Saya yakin bahwa sekali ini berfungsi, saya akan memiliki lebih banyak masalah, tetapi untuk sekarang, saya ingin ini bekerja!

Ketika saya mengubah forpernyataan itu menjadi sederhana

for item in data:
    print item

apa yang saya dapatkan adalah ... "masalah" - jadi saya melakukan sesuatu yang lebih mendasar salah. Inilah sedikit json saya:

{"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...

ketika saya mencetaknya datakelihatannya aneh sekali:

{u'issues': [{u'body': u'Add missing paging (Older>>) lin...
Amanda
sumber
Apa yang Anda lewatkan adalah print repr(data)atauimport pprint; pprint.pprint(data)
John Machin

Jawaban:

116

itemkemungkinan besar string dalam kode Anda; indeks string adalah yang ada di tanda kurung siku, misalnya gravatar_id,. Jadi pertama-tama saya akan memeriksa datavariabel Anda untuk melihat apa yang Anda terima di sana; Saya kira itu dataadalah daftar string (atau setidaknya daftar yang mengandung setidaknya satu string) sementara itu harus berupa daftar kamus.

Tamas
sumber
158

Variabelnya itemadalah string. Indeks terlihat seperti ini:

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

Contoh di atas menggunakan 0indeks string untuk merujuk ke karakter pertama.

String tidak dapat memiliki indeks string (seperti kamus dapat). Jadi ini tidak akan berhasil:

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

dataadalah sebuah dictobjek. Jadi, ulangi seperti ini:

Python 2

for key, value in data.iteritems():
    print key, value

Python 3

for key, value in data.items():
    print(key, value)
John Machin
sumber
36

TypeError untuk Slice Notation str[a:b]

tl; dr: gunakan titik dua, : bukan koma di antara dua indeks adan bdalamstr[a:b]


Ketika bekerja dengan notasi string dan slice ( operasi urutan umum ), dapat terjadi bahwa a TypeErrordinaikkan, menunjukkan bahwa indeks harus bilangan bulat, bahkan jika mereka jelas.

Contoh

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

Kami jelas melewati dua bilangan bulat untuk indeks ke notasi slice, kan? Jadi apa masalahnya di sini?

Kesalahan ini bisa sangat membuat frustrasi - terutama di awal belajar Python - karena pesan kesalahannya agak menyesatkan.

Penjelasan

Kami secara implisit melewati tupel dua bilangan bulat (0 dan 5) ke notasi slice ketika kami memanggil my_string[0,5]karena 0,5(bahkan tanpa tanda kurung) mengevaluasi untuk tuple yang sama seperti yang (0,5)akan dilakukan.

Tanda koma ,sebenarnya cukup untuk Python untuk mengevaluasi sesuatu sebagai tuple:

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

Jadi apa yang kami lakukan di sana, kali ini secara eksplisit:

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

Sekarang, setidaknya, pesan kesalahan itu masuk akal.

Larutan

Kita perlu mengganti koma , dengan titik dua : untuk memisahkan kedua bilangan bulat dengan benar:

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

Pesan kesalahan yang lebih jelas dan lebih bermanfaat bisa jadi seperti:

TypeError: string indices must be integers (not tuple)

Pesan kesalahan yang baik menunjukkan secara langsung kepada pengguna apa yang mereka lakukan salah dan akan lebih jelas bagaimana menyelesaikan masalah.

[Jadi lain kali ketika Anda menemukan diri Anda bertanggung jawab untuk menulis pesan deskripsi kesalahan, pikirkan contoh ini dan tambahkan alasan atau informasi berguna lainnya ke pesan kesalahan untuk membuat Anda dan mungkin orang lain mengerti apa yang salah.]

Pelajaran yang dipetik

  • notasi irisan menggunakan titik dua : untuk memisahkan indeksnya (dan rentang langkah, misalnya str[from:to:step])
  • tuple didefinisikan oleh koma ,(mist = 1, )
  • menambahkan beberapa informasi ke pesan kesalahan bagi pengguna untuk memahami apa yang salah

Ceria dan selamat pemrograman
winklerrr


[Saya tahu pertanyaan ini sudah dijawab dan ini bukan pertanyaan yang diajukan oleh pemula, tapi saya datang ke sini karena masalah di atas yang mengarah ke pesan kesalahan yang sama. Setidaknya butuh beberapa waktu untuk menemukan kesalahan ketik kecil itu.

Jadi saya berharap ini akan membantu orang lain yang menemukan kesalahan yang sama dan menghemat waktu mereka menemukan kesalahan kecil.]

winklerrr
sumber
0

Ini bisa terjadi jika koma hilang. Saya berlari ke dalamnya ketika saya memiliki daftar dua-tupel, yang masing-masing terdiri dari string di posisi pertama, dan daftar di yang kedua. Saya keliru menghilangkan koma setelah komponen pertama dari tuple dalam satu kasus, dan penerjemah berpikir saya mencoba untuk mengindeks komponen pertama.

dumbledad
sumber
0

Saya memiliki masalah serupa dengan Pandas, Anda harus menggunakan fungsi iterrows () untuk beralih melalui dokumentasi Pandas dataset Pandas untuk iterrows

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

perhatikan bahwa Anda perlu menangani indeks dalam dataset yang juga dikembalikan oleh fungsi.

kenang-kenangan
sumber