সিএসভি ফাইল থেকে অভিধান তৈরি করছেন?


153

আমি একটি সিএসভি ফাইল থেকে অভিধান তৈরি করার চেষ্টা করছি। সিএসভি ফাইলের প্রথম কলামে অনন্য কী রয়েছে এবং দ্বিতীয় কলামে মান রয়েছে। সিএসভি ফাইলের প্রতিটি সারি অভিধানের মধ্যে একটি অনন্য কী, মান জোড়া উপস্থাপন করে। আমি ক্লাসগুলি csv.DictReaderএবং csv.DictWriterক্লাসগুলি ব্যবহার করার চেষ্টা করেছি , তবে প্রতিটি সারিটির জন্য কীভাবে একটি নতুন অভিধান তৈরি করা যায় তা কেবল আমিই বুঝতে পারি। আমি একটি অভিধান চাই আমি যে কোডটি ব্যবহার করার চেষ্টা করছি তা এখানে:

import csv

with open('coors.csv', mode='r') as infile:
    reader = csv.reader(infile)
    with open('coors_new.csv', mode='w') as outfile:
    writer = csv.writer(outfile)
    for rows in reader:
        k = rows[0]
        v = rows[1]
        mydict = {k:v for k, v in rows}
    print(mydict)

উপরের কোডটি চালানোর সময় আমি একটি পাই ValueError: too many values to unpack (expected 2)। আমি কীভাবে একটি সিএসভি ফাইল থেকে একটি অভিধান তৈরি করব? ধন্যবাদ।


2
আপনি কি একটি ইনপুট ফাইল এবং ফলাফলের কাঠামোর উদাহরণ দিতে পারেন?
রবার্ট

1
আপনি যখন csv.reader এর মাধ্যমে পুনরাবৃত্তি করবেন, আপনি একক সারি পাবেন, সারিগুলি নয়। সুতরাং, বৈধ ফর্মটি হ'ল মাইডিক্ট = {কে: ভি ফর কে, ভি রিডার} তবে আপনি যদি নিশ্চিত হন যে সিএসভি ফাইলে কেবল দুটি কলাম রয়েছে, তবে মাইডিক্ট = ডিক (পাঠক) অনেক দ্রুত is
অ্যালেক্স লাসকিন

উত্তর:


155

আমি বিশ্বাস করি আপনি যে বাক্য গঠনটি অনুসন্ধান করেছিলেন তা নিম্নরূপ:

import csv

with open('coors.csv', mode='r') as infile:
    reader = csv.reader(infile)
    with open('coors_new.csv', mode='w') as outfile:
        writer = csv.writer(outfile)
        mydict = {rows[0]:rows[1] for rows in reader}

পর্যায়ক্রমে, অজগরটির জন্য <= 2.7.1, আপনি চান:

mydict = dict((rows[0],rows[1]) for rows in reader)

2
প্রত্যাশার চেয়ে দীর্ঘ সারিগুলির জন্য অ্যাকাউন্টে রাখা ভাল; কিন্তু যদি একটানা প্রচুর আইটেম থাকে তবে তিনি কি তার নিজস্ব ব্যতিক্রমটি উত্থাপন করবেন না? আমি মনে করি তার অর্থ হবে তার ইনপুট ডেটাতে কোনও ত্রুটি আছে।
মেশিনটি

1
এবং তারপরে তিনি কমপক্ষে ব্যতিক্রমটিকে ত্রুটিযুক্ত ইনপুট পর্যন্ত সংকুচিত করতে সক্ষম হবেন
মেশিন

এটির কিছুটা যোগ্যতা রয়েছে তবে আমি দৃ firm় বিশ্বাসী যে ব্যতিক্রমগুলি সেখানে রয়েছে তা আপনাকে বলতে যে আপনি কোনও কিছুকে ভুলভাবে প্রোগ্রাম করেছেন - এটি কখন নয় যে বিশ্ব আপনাকে লেবু দেয়। আপনি যখন খুব সুন্দর ত্রুটি বার্তা মুদ্রণ করেন এবং ব্যর্থ হন বা এই ক্ষেত্রে আরও উপযুক্ত - একটি দুর্দান্ত সতর্কতা বার্তা এবং সফল হন succeed
নাট

দুঃখিত, অপের কোডটি দেখেছেন, তিনি প্রতি লাইনে 2 টি আইটেম চাইছেন কিনা তা বলা শক্ত। আমি ভৃল ছিলাম!
19:30

1
আমার সিএসভিতে একাধিক লাইন ছিল তবে এটি কেবল 1 টি দিয়েছে: মান জুটি
অভিলাষ মিশ্র

80

ওপেন কল করে ফাইলটি খুলুন এবং তারপরে csv.DictReader

input_file = csv.DictReader(open("coors.csv"))

ইনপুট_ফাইলে পুনরাবৃত্তি করে আপনি সিএসভি ফাইল ডেক রিডার অবজেক্টের সারিগুলিতে পুনরাবৃত্তি করতে পারেন।

for row in input_file:
    print(row)

বা কেবল প্রথম লাইনে অ্যাক্সেস করতে

dictobj = csv.DictReader(open('coors.csv')).next() 

আপডেট অজগর 3+ সংস্করণে, এই কোডটি কিছুটা পরিবর্তন করবে:

reader = csv.DictReader(open('coors.csv'))
dictobj = next(reader) 

3
এটি ডিক্টরিডারটিকে একটি শব্দ না করে (এবং হ্যাঁ কোনও মূলমূল্যের জুড়ি নয়) করে তোলে
এইচএন সিং

1
@ জনাব সিং - হ্যাঁ, আমি জানি - উদ্দেশ্য ছিল এটি অন্য
কাউকেও

1
'ডিক্ট্রিডার' অবজেক্টটির 'পরের' কোনও বৈশিষ্ট্য নেই
পলক

1
@ পালাক - পাইথন ২.7 এর জবাব দেওয়া হয়েছিল, পাইথন 3+ সংস্করণের next(dictobj)পরিবর্তে চেষ্টা করুন dictobj.next()
লক্ষ্মীকান্ত রত্নপাখি

61
import csv
reader = csv.reader(open('filename.csv', 'r'))
d = {}
for row in reader:
   k, v = row
   d[k] = v

6
অত্যন্ত উচ্চ-পাইথোনিক স্টাইল।
অ্যালেক্স লাসকিন

47
@ অ্যালেক্স লাসকিন: সত্যি? এটিকে আমার কাছে বেশ পঠনযোগ্য অজগর বলে মনে হচ্ছে। এই বিবৃতি ব্যাক আপ আপনার নীতি কি? আপনি মূলত তাকে কেবল "পপি মাথা" বলেছেন ...
মেশিন

26
@ মেশিন-আকুল, না, আমি বলিনি যে তার কোডটি 'খারাপ'। তবে লেখার একক কারণ নেই for row in reader: k, v = rowযদি আপনি কেবল লিখতে পারেন for k, v in reader, উদাহরণস্বরূপ। এবং যদি আপনি প্রত্যাশা করেন যে পাঠকটি একটি পুনরাবৃত্তিযোগ্য, দ্বি-উপাদান আইটেম তৈরি করে, তবে আপনি কেবল রূপান্তরকরণের জন্য সরাসরি ডিকটিতে এটি দিতে পারেন। d = dict(reader)বিশাল ডেটাসেটগুলিতে অনেক খাটো এবং উল্লেখযোগ্যভাবে দ্রুত।
অ্যালেক্স লাসকিন

44
@ অ্যালেক্স লাসকিন: স্পষ্টির জন্য ধন্যবাদ। আমি ব্যক্তিগতভাবে আপনার সাথে একমত হয়েছি তবে আমি মনে করি আপনি যদি কারও কোডকে "নন-পাইথোনিক" কল করতে চান তবে আপনার এই মন্তব্যটির সাথে একটি ন্যায়সঙ্গত প্রমাণ দেওয়া উচিত। আমি বলব যে "সংক্ষিপ্ত" এবং "দ্রুত" অগত্যা "আরও পাইথোনিক" এর সমতুল্য নয়। পাঠযোগ্যতা / নির্ভরযোগ্যতা এছাড়াও একটি বিশাল উদ্বেগ। যদি উপরোক্ত for row in readerদৃষ্টান্তের জন্য আমাদের কিছু প্রতিবন্ধকতায় কাজ করা আরও সহজ হয় তবে এটি (দীর্ঘমেয়াদী বিকাশের পরে) আরও ব্যবহারিক হতে পারে। আমি স্বল্পমেয়াদী আপনার সাথে একমত, কিন্তু অকাল অপটিমাইজেশন থেকে সাবধান।
মেশিন

30

এটি মার্জিত নয় তবে পান্ডাস ব্যবহার করে একটি লাইন সমাধান।

import pandas as pd
pd.read_csv('coors.csv', header=None, index_col=0, squeeze=True).to_dict()

আপনি যদি আপনার সূচকের জন্য dtype নির্দিষ্ট করতে চান (আপনি যদি বাগের কারণে সূচি_কোল আর্গুমেন্ট ব্যবহার করেন তবে এটি read_csv এ নির্দিষ্ট করা যাবে না ):

import pandas as pd
pd.read_csv('coors.csv', header=None, dtype={0: str}).set_index(0).squeeze().to_dict()

3
আমার বইতে এটি সেরা উত্তর
বোর্ডটিসি

আর যদি হেডার থাকে ...?
ndtreviv

@ndtviviv আপনি হেডার উপেক্ষা করার জন্য স্কিপ্রো ব্যবহার করতে পারেন।
মুদাসসিরখান 19

17

আপনাকে কেবল csv.reader কে ডিকে রূপান্তর করতে হবে:

~ >> cat > 1.csv
key1, value1
key2, value2
key2, value22
key3, value3

~ >> cat > d.py
import csv
with open('1.csv') as f:
    d = dict(filter(None, csv.reader(f)))

print(d)

~ >> python d.py
{'key3': ' value3', 'key2': ' value22', 'key1': ' value1'}

5
সমাধানটি পরিপাটি, এবং দুর্দান্ত কাজ করবে যদি তিনি নিশ্চিত হন যে তার ইনপুটগুলিতে কোনও সারিতে কখনও কখনও তিন বা ততোধিক কলাম থাকবে না। যাইহোক, যে যদি কখনও সম্মুখীন হয়, কিছুটা ভালো একটি ব্যতিক্রম উত্থাপিত হবে: ValueError: dictionary update sequence element #2 has length 3; 2 is required
নাট

@ ম্যাচাইন, প্রশ্নের ত্রুটিটি বিচার করে, সিএসভি ফাইলটিতে 2 টিরও বেশি কলাম রয়েছে
জন লা রুয়ে

@gnibbler, না, সারিটির ডাবল আনপ্যাকিংয়ের কারণে প্রশ্নের মধ্যে ত্রুটি। প্রথমে তিনি পাঠককে পুনরাবৃত্তি করার চেষ্টা করুন, সারিগুলি পাওয়া যা আসলে একক সারি । এবং যখন তিনি এই একক সারিতে পুনরাবৃত্তি করার চেষ্টা করেন, তখন তিনি দুটি আইটেম পান, যা সঠিকভাবে আনপ্যাক করা যায় না।
অ্যালেক্স লাসকিন

একটি সাধারণ মন্তব্য: পুনরাবৃত্ত থেকে মেমরিতে রাখা অবজেক্ট তৈরি করা স্মৃতি সমস্যার কারণ হতে পারে। আপনার স্মৃতি স্থান এবং পুনরাবৃত্তিযোগ্য উত্স ফাইলের আকার পরীক্ষা করার পরামর্শ দিন। পুনরাবৃত্ত হওয়াগুলির একটি প্রধান সুবিধা (পুরো পয়েন্ট?) হ'ল বড় জিনিসগুলিকে স্মৃতিতে না রাখা।
travelingbones

@Nate: তা যদি প্রয়োজন হয় তাহলে মোড়কে সংশোধন করা যেতে পারে filterসহ কল map(operator.itemgetter(slice(2)), ...), তাই এটি শুধুমাত্র প্রথম দুটি iterms টান হবে, এটি উপার্জন: dict(map(operator.itemgetter(slice(2)), filter(None, csv.reader(f))))। যদি এটি পাইথন 2 হয় তবে তা নিশ্চিত করে নিন from future_builtins import map, filter, তাই dictএকাধিক অপ্রয়োজনীয় অস্থায়ী অস্থায়ী listপ্রথম তৈরি করার পরিবর্তে সরাসরি জেনারেটর পড়ে )
শ্যাডোর্যাঞ্জার

12

আপনি এর জন্য নম্পটি ব্যবহার করতে পারেন।

from numpy import loadtxt
key_value = loadtxt("filename.csv", delimiter=",")
mydict = { k:v for k,v in key_value }

5

আমি if rowsফাইলের শেষে একটি খালি লাইন আছে যদি যুক্ত করার পরামর্শ চাই

import csv
with open('coors.csv', mode='r') as infile:
    reader = csv.reader(infile)
    with open('coors_new.csv', mode='w') as outfile:
        writer = csv.writer(outfile)
        mydict = dict(row[:2] for row in reader if row)

উভয়ই সু-সম্পন্ন এবং সুচিন্তিত। তবে আমি যেমন উপরে বলেছি, তার সত্যটি কি সত্য প্রত্যাখ্যান করা উচিত যে তার ইনপুট লাইনটি তার প্রত্যাশার চেয়ে দীর্ঘ? আমি বলব যদি সে দুটিরও বেশি আইটেমের সাথে লাইন পায় তবে তার নিজের ব্যতিক্রমটি (কাস্টম বার্তা সহ) উত্থাপন করা উচিত।
মেশিনটি

অথবা বরং @ নেট দ্বারা উপরে বর্ণিত হিসাবে কমপক্ষে একটি সতর্কতা বার্তা মুদ্রণ করুন। এটি এমন কিছু বলে মনে হচ্ছে না যা আপনি উপেক্ষা করতে চান।
মেশিনটি

আপনার উত্তর (বনাম খনি) কিছু চিন্তা করে - এই ক্ষেত্রে কাটা এবং সূচীকরণ মধ্যে দক্ষতার পার্থক্য আছে?
নাট

1
@ ম্যাচাইন, কোনও ধারণা নেই। সম্ভবত এটি একটি ডাটাবেস থেকে ব্যবহারকারীর টেবিলের ডাম্প, এবং তিনি কেবল ইউজারিডের একটি ডিক চান: ব্যবহারকারীর নাম বা উদাহরণস্বরূপ
জন লা রুয়ে

1
ওহে ছেলেরা, মন্তব্যের জন্য ধন্যবাদ। আপনার আলোচনা আমাকে সত্যই আমার সমস্যার সমাধান করতে সহায়তা করেছে। ইনপুটটি প্রত্যাশার চেয়ে বেশি দীর্ঘ হলে পতাকা বাড়াতে সম্পর্কে ধারণাটি পছন্দ করি। আমার ডেটা একটি ডেটাবেস ডাম্প এবং আমার কাছে আরও দুটি কলামের ডেটা রয়েছে।
drbunsen


3

আপনি যদি নমপি প্যাকেজটি ব্যবহার করে ঠিক থাকেন তবে নীচের মতো কিছু করতে পারেন:

import numpy as np

lines = np.genfromtxt("coors.csv", delimiter=",", dtype=None)
my_dict = dict()
for i in range(len(lines)):
   my_dict[lines[i][0]] = lines[i][1]

3

সাধারণ সিএসভি ফাইলের জন্য যেমন নীচের

id,col1,col2,col3
row1,r1c1,r1c2,r1c3
row2,r2c1,r2c2,r2c3
row3,r3c1,r3c2,r3c3
row4,r4c1,r4c2,r4c3

আপনি কেবল বিল্ট-ইনগুলি ব্যবহার করে এটিকে পাইথন অভিধানে রূপান্তর করতে পারেন

with open(csv_file) as f:
    csv_list = [[val.strip() for val in r.split(",")] for r in f.readlines()]

(_, *header), *data = csv_list
csv_dict = {}
for row in data:
    key, *values = row   
    csv_dict[key] = {key: value for key, value in zip(header, values)}

এটি নিম্নলিখিত অভিধান উত্পন্ন করা উচিত

{'row1': {'col1': 'r1c1', 'col2': 'r1c2', 'col3': 'r1c3'},
 'row2': {'col1': 'r2c1', 'col2': 'r2c2', 'col3': 'r2c3'},
 'row3': {'col1': 'r3c1', 'col2': 'r3c2', 'col3': 'r3c3'},
 'row4': {'col1': 'r4c1', 'col2': 'r4c2', 'col3': 'r4c3'}}

দ্রষ্টব্য: পাইথন অভিধানগুলিতে অনন্য কী রয়েছে, সুতরাং আপনার সিএসভি ফাইলে যদি সদৃশ থাকে তবে আপনার idsপ্রতিটি সারি একটি তালিকায় যুক্ত করা উচিত।

for row in data:
    key, *values = row

    if key not in csv_dict:
            csv_dict[key] = []

    csv_dict[key].append({key: value for key, value in zip(header, values)})

বিশেষ দ্রষ্টব্য এই সব ব্যবহার করে সংক্ষিপ্ত করা যেতে পারে set_default: csv_dict.set_default (কী, []) পরিশেষে যোগ ({কী: KEY, জিপ মান জন্য মান (হেডার, মান)})।)
mdmjsh

আপনার .appendকমান্ডের ({কী: মান}) সিনট্যাক্সটি খুব কার্যকর ছিল। আমি row.updateপুনরাবৃত্তি করার সময় এবং DictReaderকোনও সিএসভি ফাইল থেকে তৈরি হওয়া কোনও বস্তুকে যুক্ত করার সময় একই সিনট্যাক্সটি ব্যবহার করে শেষ করেছি ।
শ্রুত 1

1

আপনি এটি ব্যবহার করতে পারেন, এটি বেশ দুর্দান্ত:

import dataconverters.commas as commas
filename = 'test.csv'
with open(filename) as f:
      records, metadata = commas.parse(f)
      for row in records:
            print 'this is row in dictionary:'+rowenter code here

1

অনেকগুলি সমাধান পোস্ট করা হয়েছে এবং আমি আমার সাথে অবদান রাখতে চাই, যা সিএসভি ফাইলে বিভিন্ন সংখ্যক কলামের জন্য কাজ করে। এটি প্রতি কলামে একটি কী দিয়ে একটি অভিধান তৈরি করে এবং প্রতিটি কীটির মান এই জাতীয় কলামের উপাদানগুলির সাথে তালিকা।

    input_file = csv.DictReader(open(path_to_csv_file))
    csv_dict = {elem: [] for elem in input_file.fieldnames}
    for row in input_file:
        for key in csv_dict.keys():
            csv_dict[key].append(row[key])

1

পান্ডার সাহায্যে এটি অনেক সহজ much ধরে নিচ্ছি আপনার সিএসভি হিসাবে নিম্নলিখিত ডেটা রয়েছে এবং আসুন এটি কল করুন test.txt/ test.csv(আপনি জানেন সিএসভি এক ধরণের পাঠ্য ফাইল)

a,b,c,d
1,2,3,4
5,6,7,8

এখন পান্ডা ব্যবহার করছি

import pandas as pd
df = pd.read_csv("./text.txt")
df_to_doct = df.to_dict()

প্রতিটি সারির জন্য, এটি হবে

df.to_dict(orient='records')

এবং এটাই.


0

একটি defaultdictএবং ব্যবহার করার চেষ্টা করুন DictReader

import csv
from collections import defaultdict
my_dict = defaultdict(list)

with open('filename.csv', 'r') as csv_file:
    csv_reader = csv.DictReader(csv_file)
    for line in csv_reader:
        for key, value in line.items():
            my_dict[key].append(value)

এটি ফিরে আসে:

{'key1':[value_1, value_2, value_3], 'key2': [value_a, value_b, value_c], 'Key3':[value_x, Value_y, Value_z]}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.