फाइल को डिक्शनरी में कैसे बदलें?


94

मेरे पास एक फाइल है जिसमें दो कॉलम हैं, यानी

1 a 
2 b 
3 c

मैं इस फाइल को एक शब्दकोश में पढ़ना चाहता हूं जैसे कि कॉलम 1 कुंजी है और कॉलम 2 मान है, अर्थात,

d = {1:'a', 2:'b', 3:'c'}

फ़ाइल छोटी है, इसलिए दक्षता कोई समस्या नहीं है।

जवाबों:


154
d = {}
with open("file.txt") as f:
    for line in f:
       (key, val) = line.split()
       d[int(key)] = val

1
क्या आप कथन के साथ समझा सकते हैं?
VGE

12
withफ़ाइल को साफ करने के लिए यहां उपयोग किया जाता है। जब आप ब्लॉक छोड़ देते हैं (या तो सामान्य निष्पादन प्रवाह या अपवाद द्वारा) तो फ़ाइल स्वचालित रूप से बंद हो जाएगी। आप यहां पायथन में संदर्भ-प्रबंधकों के बारे में अधिक पढ़ सकते हैं: effbot.org/zone/python-with-statement.htm
व्लाद एच

1
for line in open("file.txt"):उसी तरह सफाई करो। और यदि f एक स्थानीय मान fहै तो स्कोप खो जाने पर जारी किया जाता है। एकमात्र मामला जहां यह कथन उपयोगी है, यह लंबे फ़ंक्शन (गुणवत्ता के लिए अच्छा नहीं) के लिए है, या यदि आप एक वैश्विक चर का उपयोग करते हैं।
VGE

1
@VGE, उसी तरह सफाई नहींfor line in open('file.txt') करता है । सभी पायथन कार्यान्वयन समान नहीं हैं। गारंटी है कि ब्लॉक से बाहर निकलने पर फ़ाइल बंद हो जाएगी। जब लाइन पूरी हो जाती है , तो कॉल किया जा सकता है। यह होगा, लेकिन जैसे संस्करणों में आलसी कचरा संग्राहक होते हैं। withforclose CPythonIronPython
मार्क तोलोनन

2
क्या वास्तव में int यहाँ आवश्यक है? शायद वह संख्याओं को तार करना चाहता था?
GL2014

15

यह कुंजी को एक स्ट्रिंग के रूप में छोड़ देगा:

with open('infile.txt') as f:
  d = dict(x.rstrip().split(None, 1) for x in f)

2
एक सरल dict([line.split() for line in f])पर्याप्त है, इमो।
user225312

@sukhbir: यदि आप प्रश्न पढ़ते हैं, तो आप देखेंगे कि op क्या चाहता है।
साइलेंटगॉस्ट

@SilentGhost: मैंने पढ़ा है कि ओपी पूर्णांक के रूप में कुंजी चाहता है, लेकिन इग्नासियो के समाधान (और साथ ही मैंने जिसे हटा दिया है), में एक स्ट्रिंग के रूप में चाबियाँ हैं (जैसा कि खुद इग्नासियो द्वारा बताया गया है)।
user225312

मैं उलझन में था कि हमें तानाशाही तर्क में पास होने की आवश्यकता क्यों नहीं है। के dict([x.rstrip().split(None, 1) for x in f])बजाय यानी dict(x.rstrip().split(None, 1) for x in f)। एक ही बात को सोचने वालों के लिए, पूर्व सूची बोध के बजाय एक जनरेटर अभिव्यक्ति है जैसा कि यहां बताया गया है: python.org/dev/peps/pep-0289(PEP-289) । कुछ नया सीखा!
मटर

1
@peaxol: इंटरमीडिएट सूची नहीं बनाने के लिए हम सूची बोध के बजाय एक जनरेटर अभिव्यक्ति का उपयोग करते हैं।
इग्नासियो वाज़क्वेज़-अब्राम्स


5
def get_pair(line):
    key, sep, value = line.strip().partition(" ")
    return int(key), value

with open("file.txt") as fd:    
    d = dict(get_pair(line) for line in fd)

1
क्यों नहीं partition? और withबयान?
साइलेंटगॉस्ट

@SilentGhost: मुझे विभाजन के बारे में पता नहीं था! लेकिन इस मामले में str.split करना बेहतर क्यों है? "के साथ" के बारे में: शायद आप मेरे लिए इसे स्पष्ट कर सकते हैं: क्या यह फाइल डिस्क्रिप्टर के बंद होने की गुंजाइश से बाहर जाने के लिए पर्याप्त नहीं है? मुझे लगता है कि एक अपवाद मुख्य फ़ाइल खुला रहता है, मैं इसे बदल दूँगा।
टोकन

partitionतेजी से और इस उद्देश्य के लिए बनाया गया है।
SilentGhost

वर्णनकर्ता बंद है या नहीं यह कार्यान्वयन का एक विवरण है। withयह सुनिश्चित करने के लिए एक सरल तरीका है।
SilentGhost

यह अभी भी आवश्यकता होगी strip, मैं कहूँगा।
SilentGhost

3

शब्दकोश समझ से

d = { line.split()[0] : line.split()[1] for line in open("file.txt") }

या पंडों द्वारा

import pandas as pd 
d = pd.read_csv("file.txt", delimiter=" ", header = None).to_dict()[0]

पंडों द्वारा केवल पहला कॉलम
मौलिक माधवी

1
@Samer Ayoub उपरोक्त समाधान (डिक्शनरी कॉम्प्रिहेंशन) कार्य करता है यदि कुंजी और मान दोनों एक शब्द लंबे हैं। यदि मेरी पाठ फ़ाइल में निम्नलिखित डेटा हैं। मैं मान के रूप में कुंजी और विजेता टीम के रूप में वर्ष कैसे बना सकता हूं। 1903 बोस्टन अमेरिकियों 1904 कोई विश्व सीरीज 1905 न्यू यॉर्क जाइंट्स 1906 शिकागो वाइट सॉक्स 1907 शिकागो कब्स 1908 शिकागो कब्स
ऋद्धि

1
@Ridhi के जवाब के लिए खेद है। आप या तो पहले स्थान पर केवल stackoverflow.com/questions/30636248/… या विभाजन के लिए तर्क के रूप में एक नियमित अभिव्यक्ति का उपयोग कर सकते हैं ()
समीर अय्यूब

@ समरअयूब- शुक्रिया।
रिधि

1

IMHO जनरेटर का उपयोग करने के लिए थोड़ा अधिक पायथोनिक है (शायद आपको इसके लिए 2.7+ की आवश्यकता है):

with open('infile.txt') as fd:
    pairs = (line.split(None) for line in fd)
    res   = {int(pair[0]):pair[1] for pair in pairs if len(pair) == 2 and pair[0].isdigit()}

यह भी पूर्णांक से शुरू नहीं होने वाली रेखाओं को फ़िल्टर करेगा या बिल्कुल दो आइटम नहीं होगा


0
import re

my_file = open('file.txt','r')
d = {}
for i in my_file:
  g = re.search(r'(\d+)\s+(.*)', i) # glob line containing an int and a string
  d[int(g.group(1))] = g.group(2)

9
re? गंभीरता से?
साइलेंटगॉस्ट

मुझे नहीं लगता कि यह सबसे अच्छा तरीका है।
डोनोवन

@ शेफॉइड ने कहा "फ़ाइल छोटी है, इसलिए दक्षता कोई समस्या नहीं है।" split()अगर फ़ाइल प्रारूप समझदार नहीं है तो लगभग चुपचाप काम नहीं करता है।
VGE

0

यदि आप एक लाइनर से प्यार करते हैं, तो कोशिश करें:

d=eval('{'+re.sub('\'[\s]*?\'','\':\'',re.sub(r'([^'+input('SEP: ')+',]+)','\''+r'\1'+'\'',open(input('FILE: ')).read().rstrip('\n').replace('\n',',')))+'}')

इनपुट फ़ाइल = फ़ाइल का पथ, एसईपी = कुंजी-मूल्य विभाजक चरित्र

यह करने का सबसे सुंदर या कुशल तरीका नहीं है, लेकिन फिर भी यह काफी दिलचस्प है :)



0

सरल विकल्प

शब्दकोश का उपयोग करने के लिए अधिकांश तरीके JSON, अचार या लाइन रीडिंग का उपयोग करते हैं। बशर्ते आप पायथन से बाहर के शब्दकोश का संपादन नहीं कर रहे हैं, इस सरल विधि को और भी जटिल शब्दकोशों के लिए पर्याप्त होना चाहिए। हालांकि अचार बड़े शब्दकोशों के लिए बेहतर होगा।

x = {1:'a', 2:'b', 3:'c'}
f = 'file.txt'
print(x, file=open(f,'w'))    # file.txt >>> {1:'a', 2:'b', 3:'c'}
y = eval(open(f,'r').read())
print(x==y)                   # >>> True
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.