Saya bertanya-tanya apa cara paling sederhana untuk mengubah string
daftar seperti berikut ini menjadi list
:
x = u'[ "A","B","C" , " D"]'
Bahkan jika pengguna menempatkan spasi di antara koma, dan spasi di dalam tanda kutip. Saya perlu mengatasinya juga untuk:
x = ["A", "B", "C", "D"]
dalam Python.
Saya tahu saya bisa menghapus spasi dengan strip()
dan split()
menggunakan operator perpecahan dan memeriksa bukan huruf. Tetapi kode itu menjadi sangat kludgy. Apakah ada fungsi cepat yang tidak saya sadari?
Jawaban:
ast.literal_eval :
sumber
eval
, bukanast.literal_eval
.ast.literal_eval
adalah lebih aman daripadaeval
, tapi itu tidak benar-benar aman . Seperti yang dijelaskan oleh versi terbaru dokumen : "Peringatan Dimungkinkan untuk menabrak juru bahasa Python dengan string yang cukup besar / kompleks karena batasan kedalaman tumpukan pada kompiler AST Python." Pada kenyataannya, dimungkinkan untuk menjalankan kode arbitrer melalui serangan stack-smashing yang cermat, meskipun sejauh yang saya tahu tidak ada yang membangun bukti konsep publik untuk itu.The
json
modul adalah solusi yang lebih baik setiap kali ada stringified daftar kamus. Thejson.loads(your_data)
fungsi dapat digunakan untuk mengubahnya menjadi daftar.Demikian pula
sumber
'["a","b"]'
tetapi tidak untuk"['a','b']"
.Ini
eval
berbahaya - Anda seharusnya tidak mengeksekusi input pengguna.Jika Anda memiliki 2,6 atau lebih baru, gunakan ast bukan eval:
Setelah Anda memilikinya,
strip
senarnya.Jika Anda menggunakan versi Python yang lebih lama, Anda bisa mendekati apa yang Anda inginkan dengan ekspresi reguler sederhana:
Ini tidak sebagus solusi ast, misalnya ia tidak dengan benar menangani tanda kutip yang lolos dalam string. Tapi itu sederhana, tidak melibatkan eval berbahaya, dan mungkin cukup baik untuk tujuan Anda jika Anda menggunakan Python yang lebih tua tanpa ast.
sumber
eval
berbahaya - Anda tidak boleh mengeksekusi input pengguna.”? Saya menggunakan 3,6eval
secara langsung, itu akan mengevaluasi ekspresi python yang valid, yang berpotensi berbahaya.literal_eval
Memecahkan masalah ini dengan hanya mengevaluasi struktur literal Python: string, angka, tuple, daftar, dicts, boolean, dan Tidak ada.sumber
Ada solusi cepat:
Ruang putih yang tidak diinginkan dalam elemen daftar dapat dihapus dengan cara ini:
sumber
Terinspirasi dari beberapa jawaban di atas yang berfungsi dengan paket python dasar saya membandingkan kinerja beberapa (menggunakan Python 3.7.3):
Metode 1: ast
Metode 2: json
Metode 3: tidak ada impor
Saya kecewa melihat apa yang saya anggap metode dengan keterbacaan terburuk adalah metode dengan kinerja terbaik ... ada pengorbanan untuk dipertimbangkan ketika pergi dengan opsi yang paling mudah dibaca ... untuk jenis beban kerja yang saya gunakan python karena saya biasanya nilai keterbacaan atas opsi yang sedikit lebih banyak performan, tetapi seperti biasa itu tergantung.
sumber
Jika hanya daftar satu dimensi, ini dapat dilakukan tanpa mengimpor apa pun:
sumber
Dengan asumsi bahwa semua input Anda adalah daftar dan bahwa tanda kutip ganda pada input sebenarnya tidak masalah, ini dapat dilakukan dengan penggantian regexp sederhana. Ini agak perl-y tetapi bekerja seperti pesona. Perhatikan juga bahwa output sekarang adalah daftar string unicode, Anda tidak menentukan bahwa Anda membutuhkannya, tetapi tampaknya masuk akal jika diberikan input unicode.
Variabel junker berisi regexp yang dikompilasi (untuk kecepatan) dari semua karakter yang tidak kita inginkan, menggunakan] sebagai karakter yang diperlukan beberapa tipuan backslash. Re.sub menggantikan semua karakter ini dengan tidak ada, dan kami membagi string yang dihasilkan di koma.
Perhatikan bahwa ini juga menghilangkan spasi dari entri dalam u '["oh tidak"]' ---> [u'ohno ']. Jika ini bukan yang Anda inginkan, regexp perlu ditingkatkan sedikit.
sumber
Jika Anda tahu bahwa daftar Anda hanya berisi string yang dikutip, contoh pyparsing ini akan memberi Anda daftar string yang dilucuti (bahkan mempertahankan Unicode-ness asli).
Jika daftar Anda dapat memiliki lebih banyak tipe data, atau bahkan berisi daftar di dalam daftar, maka Anda akan memerlukan tata bahasa yang lebih lengkap - seperti yang ada di wiki pyparsing ini, yang akan menangani tupel, daftar, int, float, dan string yang dikutip. Akan bekerja dengan versi Python kembali ke 2.4.
sumber
parsePythonValue.py
contoh adalah sekarang GitHub di github.com/pyparsing/pyparsing/blob/master/examples/...Untuk melengkapi jawaban @Ryan menggunakan json, satu fungsi yang sangat mudah untuk mengonversi unicode adalah yang diposting di sini: https://stackoverflow.com/a/13105359/7599285
ex dengan tanda kutip ganda atau tunggal:
sumber
Saya ingin memberikan solusi pola yang lebih intuitif dengan regex. Fungsi di bawah ini mengambil input daftar string yang berisi string arbitrer.
Penjelasan bertahap: Anda menghapus semua spasi putih, tanda kurung, dan value_separator (asalkan itu bukan bagian dari nilai yang ingin Anda ekstrak, kalau tidak buat regex lebih kompleks). Kemudian Anda membagi string yang telah dibersihkan pada tanda kutip tunggal atau ganda dan mengambil nilai yang tidak kosong (atau nilai indeks ganjil, apa pun preferensi).
testample : "['21'," foo "'6', '0'," A "]"
sumber
dan dengan python murni - tidak mengimpor perpustakaan apa pun
sumber
Anda dapat mengalami masalah seperti itu saat berurusan dengan data yang tergores yang disimpan sebagai Pandas DataFrame.
Solusi ini berfungsi seperti pesona jika daftar nilai hadir sebagai teks .
sumber
Jadi, dengan mengikuti semua jawaban, saya memutuskan untuk menggunakan metode yang paling umum:
Jadi pada akhirnya regex menang!
sumber
Anda dapat menyimpan sendiri .strip () fcn hanya dengan memotong karakter pertama dan terakhir dari representasi string dari daftar (lihat baris ketiga di bawah)
sumber