Python/알면 쓸모있는 잡다한 코드

Dictionary within Dictionary 이중 딕셔너리

joannekim0420 2021. 11. 25. 12:36
728x90

상황: 11개 폴더 안에 200~300개의 여러 파일들이 있는데 (각 폴더 안에 파일도 같은 이름으로 있을 수도 없을 수도)

       같은 파일명끼리 그리고 파일 안 같은 라인끼리 추출해야함!

그림과 같이 언어 이름으로 된 폴더 안에 TextData1.txt 같이 파일이 있고 각 파일 안에는 고유 태그 이름과 용어가 있다.

 

1. 언어별로 같은 파일이름 TextData1, TextData2 ... TextData100 으로 된 파일의 존재 여부를 확인(가끔 언어별로 파일이 없을 수도 있기 때문)

→ 각 파일 이름을 딕셔너리 key 로 value는 해당 언어명을 저장한다!

import collections
file_name_dict= collections.defaultdict(list)

# {'file_name' : ['lang1','lang2'...]}
for lst, l in zip((PT,CHS,CHT,EN,FR,DE,JA,KR,RU,TH,VI),lang):
    add_filename_dict(lst,l)
    
# check if dictionary is in correct form
for key, value in file_name_dict.items():
    print(f"{key}    {value} ")

output

 

2. 각 파일에 대한 각 라인별 고유 태그와 용어를 저장해야하는데, 이중 딕셔너리와 튜플까지 사용한다.

total_list_dict = collections.defaultdict(list)

def extract_matching_lines_by_tag():
    for file_name in file_name_dict.items():
    # file_name[0] => key
    # file_name[1] => value
    	
        # line_name_dict for tag as key and each language and word information
        line_name_dict = collections.defaultdict(list)
        # Dictionary will be like => {'tag':[(lang,word),(lang,word)...(lang,word)]}
        
        for l in lang:	
            in_path = "./" + l+"/"+file_name[0]
            
            # Files only in that language folder
            if l in file_name[1]:
                
                # some files in utf-8, some files in utf-16 
                try:
                    fread = open(in_path, "r",encoding="utf-16")
                    lines = fread.readlines()	#read all lines in one file
                except:
                    fread = open(in_path, "r",encoding="utf-16")
                    lines = fread.readlines()

				# for each line in all lines
                for line in lines:  
                    line = line.strip()
                    line = re.sub("\n","",line)
                    unique_tag_pattern = "<tag_.+?\">"
					
                    #find unique tag in each line and save the tag name 
                    tag = re.findall(unique_tag_pattern, line)
                    
                    #extract only the word necessary and remove all unnecessary tags
                    line_in_need = re.sub("<.+?>","",line)
                    line_in_need = line_in_need.strip()

					#if there is no tag in line
                    if bool(tag) == False:
                        continue
                    else:
                        for t in tag:
                        	# only add if there is word you want
                            if line_in_need != "":
                            	# value must be (lang, word) tuple form - need info on what word that language is
                                line_name_dict[t].append((l,line_in_need))
                                
		# if one file is done on all language add the dictionary to another dictionary
        # double dictionary form  {{'file name' : {'unique_tag_name' : [(lang,word)],[(lang,word)]}} 
        total_list_dict[file_name[0]].append(line_name_dict)
extract_matching_lines_by_tag()

# check if dictionary form is correct
for key, value in total_list_dict.items():
    print(f"{key}    {value} ")
    break

break 로 total_list_dict의 딕셔너리 안에 한 파일만 출력해 보았다. (이유: 모든 파일 다 출력하면 memory error 발생)

 

이제 이 딕셔너리 속 정보는 알아서 활용! 

나는 파일별로 저장하는게 목표

 

for key,value in total_list_dict.items():
    out_path = "./RESULT/"+key
    fwrite = open(out_path,"w",encoding="utf-8")  
    
    # line_name_dict 와 같음. 라인별 (언어,용어) 접근 위해 딕셔너리 따로 value_dict로 저장
    value_dict = value[0]
    
    # k = unique_tag_name , v = (lang,word) pair list
    for k,v in value_dict.items():        
    	v_list = {}
        
        # save needed languages in line
        for i in range(len(v)):
            v_list[v[i][0]] = v[i][1]
            
        # if language is in each line
        for l in lang:
            if l in v_list:
            
              if l == "Portuguese" :
                      fwrite.write(v_list[l]+"\t")
                  elif l == "Chinese" :
                      fwrite.write(v_list[l]+"\t")
                  elif l == "English" :
                      fwrite.write(v_list[l]+"\t")
                  elif l == "French" :
                      fwrite.write(v_list[l]+"\t")
                  ## add all language 
                  elif l == "Vietnamese":
                    fwrite.write(v_list[l]+"\n") #last lanugage, seperate by line
         
         	# if language does not exist in line fill it with blank
         	else:
                if l == "Vietnamese":
                    fwrite.write("\t\n")

                else:
                    fwrite.write("\t")
   
	# save by file name
	fwrite.close()