เราสามารถใช้วิธี:
inputfile = open(filename)
for line in inputfile:
work_on_the_line
เช่นโค้ดข้างล่างเปิดไฟล์ /usr/share/dict/words
แล้วอ่านทีละบรรทัด โดยที่แต่ละบรรทัดอยู่ในตัวแปร word
ด้วยคำสั่ง for word in inputfile:
#หาคำที่เป็น palindrome (คำที่กลับหน้าหลังแล้วเหมือนเดิม)
inputfile = open('/usr/share/dict/words') #เปิดไฟล์ที่มีคำภาษาอังกฤษบรรทัดละหนึ่งคำ
for word in inputfile: #อ่านเข้ามาทีละบรรทัด เก็บบรรทัดไว้ในตัวแปร word
word = word.strip() #strip() จะลบตัวอักษรที่มองไม่เห็น (white spaces) ด้านหน้าและด้านหลังของคำ รวมถึงตัวอักษรขึ้นบรรทัดใหม่ (newline, \n)
if len(word) <= 2: #ถ้าคำยาวไม่เกิน 2 ตัวอักษร เราจะไม่นับมันเป็น palindrome
continue
if word == word[::-1]: #word[::-1] หมายถึงการกลับหลังมาหน้า ดูส่วน "slices" ที่ https://snakify.org/en/lessons/lists/
print(word)
aba acca adda affa aga aha ajaja aka ala alala alula ama amma ana anana anna apa ara arara atta ava awa bib bob boob bub civic dad deed deedeed degged did dod dud eke elle eme ere eve ewe eye gag gig gog hah hallah huh ihi imi immi kakkak kayak keek kelek lemel level maam madam mem mesem mim minim mum murdrum nan non noon nun oho otto pap peep pep pip poop pop pup radar redder refer repaper retter rever reviver rotator rotor siris sis sooloos tat tebbet teet tenet terret tit toot tot tst tut tyt ulu ululu umu utu waw wow yaray yoy
inputfile = open('/usr/share/dict/words')
max_word = "" #คำที่ยาวที่สุดที่เราเคยเห็น เนื่องจากตอนนี้ยังไม่เห็นสักคำ มันจึงเป็นคำว่างๆไม่มีตัวอักษรอะไร
for word in inputfile:
word = word.strip()
if len(word) > len(max_word): #ถ้าคำที่พึ่งอ่านเข้ามายาวกว่าคำที่ยาวที่สุดที่เราเคยเห็น...
max_word = word #...เราก็เปลี่ยนคำที่ยาวทีสุดที่เราเคยเห็นเป็นคำนี้
print(max_word, len(max_word)) #len(x) คือความยาวของ x ว่ามีกี่ตัวอักษร นอกจากนี้ len ยังใช้บอกจำนวนของใน list, dictionary, ฯลฯ ด้วย
formaldehydesulphoxylate 24
เนื่องจากในโค้ดข้างบน เราเปรียบเทียบแบบ if len(word) > len(max_word):
คือถ้าคำมีความยาวเท่าๆกัน เราจะจำเฉพาะคำแรกเท่านั้น เพราะเราจะเปลี่ยนคำที่จำก็ต่อเมื่อคำใหม่มีความยาวมากกว่าคำเก่า ถ้าจะหาคำทุกคำที่มีความยาว 24 ตัวอักษรเราก็สามารถหาแบบนี้ตรงๆได้:
inputfile = open('/usr/share/dict/words')
for word in inputfile:
word = word.strip()
if len(word) == 24: #ดูเฉพาะคำที่มี 24 ตัวอักษร
print(word, len(word))
formaldehydesulphoxylate 24 pathologicopsychological 24 scientificophilosophical 24 tetraiodophenolphthalein 24 thyroparathyroidectomize 24
บางทีเราอาจจะสนใจคำที่ยาวๆโดยไม่จำเป็นต้องยาวที่สุด เช่นถ้าอยากเห็นคำที่ยาวตั้งแต่ 20 ตัวอักษรขึ้นไปเราก็อาจทำอย่างนี้ได้:
inputfile = open('/usr/share/dict/words')
long_words = [] #สร้าง list ชื่อ long_words เพื่อเก็บคำยาวๆหลายๆคำ ถ้าไม่คุ้นเคยให้อ่านที่ https://snakify.org/en/lessons/lists/
for word in inputfile:
word = word.strip()
if len(word) >= 20: #ถ้าคำมี 20 ตัวอักษรขึ้นไป...
long_words.append(word) #...ให้เอาคำนั้นไปใส่เพิ่มใน list ที่ชื่อ long_words
print(long_words)
['abdominohysterectomy', 'acetylmethylcarbinol', 'acetylphenylhydrazine', 'aminoacetophenetidine', 'anarchoindividualist', 'anatomicochirurgical', 'anatomicopathological', 'anatomicophysiologic', 'anatomicophysiological', 'anemometrographically', 'anthrohopobiological', 'anthropoclimatologist', 'anthropogeographical', 'anthropomorphization', 'anthropomorphological', 'anthropomorphologically', 'anthropomorphotheist', 'anthropophysiography', 'anthropoteleological', 'antianthropomorphism', 'anticonfederationist', 'anticonstitutionalist', 'anticonstitutionally', 'antiprestidigitation', 'antitintinnabularian', 'appendorontgenography', 'aquopentamminecobaltic', 'Archaeopterygiformes', 'arteriosympathectomy', 'autodepolymerization', 'barothermohygrograph', 'benzalphenylhydrazone', 'benzofuroquinoxaline', 'Biblicopsychological', 'blepharochromidrosis', 'blepharoconjunctivitis', 'blepharohematidrosis', 'blepharosphincterectomy', 'bronchoaspergillosis', 'bronchoesophagoscopy', 'calcareoargillaceous', 'characteristicalness', 'chemicomineralogical', 'chemicopharmaceutical', 'chemicophysiological', 'Chlamydobacteriaceae', 'chlamydobacteriaceous', 'cholecystenterorrhaphy', 'cholecystenterostomy', 'cholecystgastrostomy', 'cholecystnephrostomy', 'cholecystoduodenostomy', 'cholecystogastrostomy', 'cholecystojejunostomy', 'cholecystolithotripsy', 'cholecystonephrostomy', 'choledochoduodenostomy', 'choledochoenterostomy', 'choledocholithotripsy', 'chromophotolithograph', 'chronocinematography', 'cinephotomicrography', 'compartmentalization', 'constitutionalization', 'consubstantiationist', 'counterdemonstration', 'counterdisengagement', 'counterestablishment', 'counterexcommunication', 'counterexpostulation', 'counterinterpretation', 'counterpronunciamento', 'counterreconnaissance', 'counterrevolutionary', 'counterrevolutionist', 'counterrevolutionize', 'cryptocrystallization', 'crystallographically', 'crystalloluminescence', 'dacryocystoblennorrhea', 'dacryocystorhinostomy', 'dacryocystosyringotomy', 'deanthropomorphization', 'decahydronaphthalene', 'deintellectualization', 'desoxycorticosterone', 'diphenylchloroarsine', 'diphenylquinomethane', 'disdenominationalize', 'disestablishmentarian', 'disproportionableness', 'disproportionateness', 'duodenocholecystostomy', 'duodenocholedochotomy', 'duodenopancreatectomy', 'electrocardiographic', 'electrocauterization', 'electrochronographic', 'electrocontractility', 'electroencephalogram', 'electroencephalograph', 'electroencephalography', 'electrometallurgical', 'electrophysiological', 'electropneumatically', 'electrosynthetically', 'electrotelethermometer', 'electrotherapeutical', 'encephalomeningocele', 'enterocholecystostomy', 'epididymodeferentectomy', 'epididymodeferential', 'establishmentarianism', 'formaldehydesulphoxylate', 'formaldehydesulphoxylic', 'galvanocauterization', 'galvanocontractility', 'gastroenteroanastomosis', 'gastroenterocolostomy', 'gastrohysterorrhaphy', 'glossolabiolaryngeal', 'glossolabiopharyngeal', 'hematospectrophotometer', 'hepaticoduodenostomy', 'heterochromatization', 'heterotransplantation', 'hexachlorocyclohexane', 'hexamethylenetetramine', 'hexanitrodiphenylamine', 'hexosemonophosphoric', 'histomorphologically', 'historicocabbalistical', 'historicogeographical', 'historicophilosophica', 'homeotransplantation', 'hydrometallurgically', 'hydropneumopericardium', 'hydroxyanthraquinone', 'hypercholesterinemia', 'hypercholesterolemia', 'hyperconscientiousness', 'hyperdolichocephalic', 'hyperphosphorescence', 'hypsibrachycephalism', 'hypsidolichocephalic', 'hypsidolichocephalism', 'incomprehensibleness', 'incontrovertibleness', 'indigotindisulphonic', 'indistinguishability', 'indistinguishableness', 'institutionalization', 'intellectualistically', 'intercommunicability', 'intercrystallization', 'interdestructiveness', 'interdifferentiation', 'internationalization', 'interparenthetically', 'intertransformability', 'keratoconjunctivitis', 'labioglossolaryngeal', 'labioglossopharyngeal', 'labyrinthibranchiate', 'laparocholecystotomy', 'laparocolpohysterotomy', 'lithochromatographic', 'lymphangioendothelioma', 'macracanthrorhynchiasis', 'mandibulosuspensorial', 'mechanicocorpuscular', 'mechanicointellectual', 'Mediterraneanization', 'membranocartilaginous', 'meningoencephalocele', 'metaphenylenediamine', 'microcinematographic', 'microcolorimetrically', 'microcryptocrystalline', 'microcrystallography', 'microseismometrograph', 'monobromoacetanilide', 'naphthalenesulphonic', 'naphthylaminesulphonic', 'neurochorioretinitis', 'nondenominationalism', 'noninterchangeability', 'noninterventionalist', 'nonrepresentationalism', 'omnirepresentativeness', 'oophorosalpingectomy', 'ophthalmoblennorrhea', 'ophthalmodiastimeter', 'ophthalmodynamometer', 'ophthalmothermometer', 'orbiculatoelliptical', 'orthodolichocephalic', 'otorhinolaryngologic', 'otorhinolaryngologist', 'overindustrialization', 'palaeoanthropography', 'palaeodendrologically', 'palaeometeorological', 'paleoanthropological', 'paleodendrologically', 'pancreaticoduodenostomy', 'pancreaticogastrostomy', 'pancreatoduodenectomy', 'pancreatoenterostomy', 'parallelogrammatical', 'paraphenylenediamine', 'pathologicoanatomical', 'pathologicohistological', 'pathologicopsychological', 'pectinatodenticulate', 'pentamethylenediamine', 'pericardiomediastinitis', 'peritoneopericardial', 'pharmacoendocrinology', 'pharyngoepiglottidean', 'phenolsulphonephthalein', 'philodestructiveness', 'philoprogenitiveness', 'philosophicohistorical', 'philosophicojuristic', 'philosophicoreligious', 'philosophicotheological', 'phlebarteriodialysis', 'phoneticogrammatical', 'phoneticohieroglyphic', 'photochromolithograph', 'photochronographical', 'photochronographically', 'photospectroheliograph', 'photospectroscopical', 'phototelegraphically', 'physicophilosophical', 'physicophysiological', 'physiologicoanatomic', 'phytopaleontological', 'piezocrystallization', 'platybrachycephalous', 'platydolichocephalic', 'platydolichocephalous', 'plethysmographically', 'pneumatotherapeutics', 'pneumohydropericardium', 'pneumoventriculography', 'poliencephalomyelitis', 'polioencephalomyelitis', 'poluphloisboiotatotic', 'predisadvantageously', 'premisrepresentation', 'preterdiplomatically', 'proconstitutionalism', 'Prorhipidoglossomorpha', 'prostatovesiculectomy', 'protobasidiomycetous', 'protocatechualdehyde', 'protransubstantiation', 'pseudoanthropological', 'pseudoconglomeration', 'pseudohermaphroditic', 'pseudohermaphroditism', 'Pseudolamellibranchia', 'Pseudolamellibranchiata', 'pseudolamellibranchiate', 'pseudomonocotyledonous', 'pseudoparenchymatous', 'pseudoparthenogenesis', 'pseudophenanthroline', 'psychophysiologically', 'pylethrombophlebitis', 'pyopneumocholecystitis', 'pyopneumopericardium', 'pyopneumoperitonitis', 'reticulatocoalescent', 'roentgenographically', 'saccharogalactorrhea', 'saccharomucilaginous', 'scientificogeographical', 'scientificohistorical', 'scientificophilosophical', 'scientificoreligious', 'scleroconjunctivitis', 'scleroticochorioiditis', 'scleroticochoroiditis', 'semiprofessionalized', 'spectromicroscopical', 'spectrophotoelectric', 'spectropyrheliometer', 'spinulosodenticulate', 'spondylotherapeutics', 'stereophotogrammetry', 'stereophotomicrograph', 'stereophotomicrography', 'stereoroentgenography', 'subjectivoidealistic', 'superincomprehensible', 'superphlogistication', 'superserviceableness', 'supersuperabundantly', 'superultrafrostified', 'syncategorematically', 'teleoroentgenography', 'tessarescaedecahedron', 'tetraiodophenolphthalein', 'theoanthropomorphism', 'theologicoastronomical', 'theologicohistorical', 'theologicometaphysical', 'thermophosphorescence', 'thermopolymerization', 'thoracogastroschisis', 'thymolsulphonephthalein', 'thyroparathyroidectomize', 'thyroparathyroidectomy', 'transubstantiationalist', 'transubstantiationite', 'transubstantiatively', 'tribophosphorescence', 'trihemitetartemorion', 'turbinatocylindrical', 'tychoparthenogenesis', 'ultradolichocephalic', 'ultraphotomicrograph', 'ultrastandardization', 'uncharacteristically', 'uncontradictableness', 'uncontrovertableness', 'uncontrovertibleness', 'undiscriminatingness', 'undistinguishableness', 'unextinguishableness', 'unproportionableness', 'uranostaphylorrhaphy', 'ureterocystanastomosis', 'ureteropyelonephritis', 'ureterosalpingostomy', 'ureterosigmoidostomy', 'vagoglossopharyngeal', 'zoologicoarchaeologist', 'zygomaticoauricularis']
ถ้าเราอยากรู้ว่าคำที่มีตัวอักษร 1, 2, 3,..., 24 ตัว มีอย่างละกี่คำเราก็อาจทำตรงๆอย่างนี้ได้ แบบนี้จะมีการอ่านไฟล์ 24 ครั้ง:
print("#letters\t#words") #พิมพ์่ชื่อคอลัมน์ให้คนอ่าน
for letters in range(1,25): #letters คือจำนวนตัวอักษร เริ่มจาก 1 ไปถึง 25-1 = 24 เพราะเรารู้ว่าคำยาวสุดมี 24 อักษร
count = 0 #จำนวนคำที่มี "letters" ตัวอักษร
inputfile = open('/usr/share/dict/words') #อ่านรายการคำ หนึ่งบรรทัดมีหนึ่งคำ
for word in inputfile: #อ่านไปทีละบรรทัด
word = word.strip() #ลบตัวขึ้นบรรทัดใหม่ (\n หรือ new line)
if word[0] in "abcdefghijklmnopqrstuvwxyz": #ดูเฉพาะคำที่ขึ้นต้นด้วยอักษรตัวเล็กเท่านั้น ไม่ดูพวกชื่อเฉพาะ
if len(word) == letters: #ดูเฉพาะคำที่มีตัวอักษร letters ตัว แล้วเพิ่มจำนวนใน count
count = count + 1
print(f"{letters}\t\t{count}") #แสดงผลด้วย f-string (ดู #3 ที่ https://realpython.com/python-string-formatting/)
#letters #words 1 26 2 121 3 1135 4 4347 5 8497 6 15066 7 20552 8 26434 9 28833 10 27924 11 23773 12 18837 13 13877 14 9151 15 5585 16 3223 17 1738 18 815 19 417 20 194 21 81 22 40 23 16 24 5
def double(x):
"รับค่า x เข้าไปแล้วคำนวณค่า 2*x ให้"
return(2*x)
def is_even(x):
"ดูว่า x เป็นเลขคู่หรือไม่"
if x % 2 == 0: #ถ้าเศษจากการหารด้วย 2 เป็น 0 ก็แสดงว่าเป็นเลขคู่
return(True)
else:
return(False)
def starts_with_small_letter(word):
"ดูว่าตัวอักษรแรกใน word เป็นอักษรตัวเล็กหรือไม่"
small_letters = "abcdefghijklmnopqrstuvwxyz"
if word[0] in small_letters:
return(True)
else:
return(False) #ถ้าตัวแรกไม่อยู่ใน a-z เราก็ถือว่าคำนั้นไม่ได้ขึ้นต้นด้วยอักษรตัวเล็ก
def number_of_words_with_length(n, list_of_words):
"ดูคำในไฟล์ list_of_words ว่ามีกี่คำที่มี n ตัวอักษร"
inputfile = open(list_of_words)
count = 0
for word in inputfile:
word = word.strip()
if starts_with_small_letter(word):
if len(word) == n:
count = count + 1
return(count)
double(100) #ควรคำนวณออกมาเป็น 200
200
is_even(15) #ควรเป็น False เพราะ 15 ไม่ใช่เลขคู่
False
starts_with_small_letter("kangaroo") #ควรเป็น True เพราะ "kangaroo" ขึ้นต้นด้วยอักษรตัวเล็ก
True
number_of_words_with_length(11, "/usr/share/dict/words") #ควรเป็น 23773 เมื่อเทียบกับด้านบน
23773
ลองนับจำนวนคำที่มีตัวอักษรตั้งแต่ 1, 2, 3, ..., 24 อีกที โดยใช้ฟังก์ชั่น number_of_words_with_length()
ด้านบน
ทำแบบนี้โค้ดจะดูสั้นลง แต่ก็ยังอ่านไฟล์หลายรอบเหมือนกัน เราสามารถเขียนโค้ดให้อ่านไฟล์ครั้งเดียวแล้วทำอะไรให้เสร็จไปเลยดังที่จะเขียนต่อไปด้านล่าง
#โค้ดดูสั้นลง แต่อ่านไฟล์ 24 ครั้งเหมือนเดิม เพราะทุกครั้งที่ฟังก์ชั่น number_of_words_with_length ทำงานจะมีการอ่านไฟล์ 1 ครั้ง
print("#letters\t#words")
for letters in range(1,25):
count = number_of_words_with_length(letters, "/usr/share/dict/words")
print(f"{letters}\t\t{count}")
#letters #words 1 26 2 121 3 1135 4 4347 5 8497 6 15066 7 20552 8 26434 9 28833 10 27924 11 23773 12 18837 13 13877 14 9151 15 5585 16 3223 17 1738 18 815 19 417 20 194 21 81 22 40 23 16 24 5
ตัวอย่างนับคำที่ความยาวต่างๆโดยอ่านไฟล์ครั้งเดียว
"""
อ่านไฟล์ครั้งเดียว เก็บจำนวนคำที่มีความยาว n อักษรไว้ใน count[n]
count ต้องยาว 25 แทนที่จะเป็น 24 เพราะเราต้องการ count[24] ด้วยเพราะคำที่ยาวที่สุดยาว 24 ตัวอักษร
ทำแบบนี้เร็วกว่าแบบข้างบนที่อ่านไฟล์ 24 ครั้ง
"""
print("#letters\t#words")
count = [0] * 25 #count เป็น list = [0, 0, 0, ..., 0] มี 0 25ตัว
inputfile = open('/usr/share/dict/words')
for word in inputfile:
word = word.strip()
if starts_with_small_letter(word):
count[len(word)] += 1
for length in range(1,25):
print(f"{length}\t\t{count[length]}")
#letters #words 1 26 2 121 3 1135 4 4347 5 8497 6 15066 7 20552 8 26434 9 28833 10 27924 11 23773 12 18837 13 13877 14 9151 15 5585 16 3223 17 1738 18 815 19 417 20 194 21 81 22 40 23 16 24 5
เราสามารถเอาจำนวนคำใน count[]
มาวาดกราฟได้ด้วย matplotlib ดังนี้ จะเห็นว่าคำยาว 9 ตัวอักษรมีจำนวนมากที่สุด:
%matplotlib inline
import matplotlib.pyplot as plt
lengths = range(1,25) #ความยาวคำตั้งแต่ 1 ถึง 24 ตัวอักษร
numwords = count[1:] #count[]เก็บจำนวนคำที่มีความยาว n อักษรไว้ใน count[n]
plt.bar(lengths, numwords, align='center', alpha=0.5)
plt.xticks(lengths, lengths)
plt.title('Number of words vs. word length')
plt.xlabel('Word length in characters')
plt.ylabel('Number of words')
plt.show()