본문 바로가기
C#

Dictionary 정리 : 기초부터 활용까지

by Oz Driver 2025. 7. 23.

프로그래밍을 하다보면, 어떤 키워드에 해당하는 정보를 빠르게 찾아야 할 때가 많습니다.
예를 들면, 이름으로 전화번호를 찾거나, 아이템 이름으로 가격을 찾는 상황 등이 있습니다.
이럴 때 유용하게 쓰이는 게 바로 Dictionary입니다.

 

Dictionary 란?

Dictionary는 말 그대로 "사전" 입니다.
Key와 Value를 한 쌍으로 묶어서 데이터를 저장하는 구조입니다.

배열이나 리스트는 숫자 인덱스로 값을 찾지만, Dictionary는 key 로 값 (value) 을 바로 찾을 수 있어서 훨씬 직관적입니다. 

 

우리 생활 속 Dictionary

•   이름으로 전화번호 찾기
   예) 김아무개 : 010-1234-5678

•   학번으로 이름 찾기
   예) 2025821000 : 김아무개

 

Dictionary 의 특징

•   키 (Key) 를 이용해 값 (Value) 을 바로 찾는 해시 테이블 기반이므로 시간 복잡도는 O(1) 입니다.
•   Key 값은 고유해야 합니다. (중복 불가)
•   Value 값은 중복 가능합니다.
•   KeyValuePair<TKey, TValue> 구조체를 여러 개 담은 구조가 Dictionary 입니다.

public struct KeyValuePair<TKey, TValue>
{
    private readonly TKey key;
    private readonly TValue value;
}

 

원형과 선언

원형은 Dictionary<TKey, TValue> 이며, TKey 는 key 타입,  TValue 는 value 타입입니다.

그리고 선언은 다음과 같이 쓸 수 있습니다. 

// key : string 형, value : int 형
Dictionary<string, int> scoreTable = new Dictionary<string, int>();
   
// key : string 형, value : string 형
Dictionary<string, string> questTable = new Dictionary<string, string>();

// key : string 형, value : Item 구조체
struct Item
{ 
    public string name;
    public string desc;
    public int price;
}
Dictionary<string, Item> itemTable = new Dictionary<string, Item>();

 

데이터 추가 

Add() 함수 사용

이 방식은 key 값이 중복일 경우, 예외를 발생시킵니다.

scoreTable.Add("alice", 85);
scoreTable.Add("bob", 90);
scoreTable.Add("james", 78);

 

Index ( [ ] ) 사용

이 방식은 key 값이 중복일 경우, 예외를 발생시키지 않고 덮어씁니다. 

scoreTable["alice"] = 85;
scoreTable["bob"] = 90;
scoreTable["john"] = 78;
scoreTable["lee"] = 91;

// 예외 없이 덮어씀
scoreTable["john"] = 83;

 

중괄호를 이용한 초기화

Dictionary<string, string> phoneBook1 = new Dictionary<string, string>()
{
    { "1번 사람", "010 - 1234 - 1234" },
    { "2번 사람", "010 - 1234 - 2345" },
    { "3번 사람", "010 - 1234 - 3456" },
    { "4번 사람", "010 - 1234 - 4567" },
    { "5번 사람", "010 - 1234 - 5678" },
};

또는 () 생략 가능

Dictionary<string, string> phoneBook2 = new Dictionary<string, string>
{
    { "1번 사람", "010 - 1234 - 1234" },
    { "2번 사람", "010 - 1234 - 2345" },
    { "3번 사람", "010 - 1234 - 3456" },
    { "4번 사람", "010 - 1234 - 4567" },
    { "5번 사람", "010 - 1234 - 5678" },
};

 

값 조회

Index ( [ ] ) 사용

이 방식은 찾고자 하는 key 가 없을 경우, 예외를 발생시킵니다.

// key 가 없으면 예외 발생
int score = scoreTable["alice"];

 

이 방식을 사용하면, 직접 값을 바꾸는 것이 가능합니다. 다만, 위에서 언급했듯이 예외가 발생할 수 있으므로 간단하지만, 조심스럽게 사용해야 합니다. 

scoreTable["alice"] = 95;
scoreTable["alice"]++;

 

TryGetValue () 를 이용

이 방식은 찾고자 하는 key 가 없을 경우, 예외를 발생시키지 않는 대신 false 를 반환합니다. 

if (scoreTable.TryGetValue("alice", out int score))
{
    Console.WriteLine(score);
}
else
{
    Console.WriteLine("해당 이름이 없습니다.");
}

 

이 방식을 사용하면, 다음과 같이 값을 변경해서 넣어주어야 하는 불편함은 있습니다. 

if (scoreTable.TryGetValue("alice", out int score))
{
    score++;
    scoreTable["alice"] = score;
}
else
{
    Console.WriteLine("해당 이름이 없습니다.");
}

 

값 삭제

scoreTable.Remove("bob");

 

실패할 경우의 처리가 필요하다면, 다음과 같이 작성하면 됩니다.

if (scoreTable.Remove("bob"))
    Console.WriteLine("삭제 성공");
else
    Console.WriteLine("삭제 실패");

 

전체 비우기 

// 모든 항목 삭제
scoreTable.Clear();

 

foreach 순회

Dictionary 는 내부적으로 Key와 Value를 한 쌍으로 저장하는 KeyValuePair<TKey, TValue> 구조체의 집합입니다.
그래서 foreach() 문으로 Dictionary 를 순회하면, 반복자(IEnumerator) 가 하나씩 꺼내주는 요소의 타입은 KeyValuePair<string, int> 형태가 됩니다. 이 타입은 길고 복잡하기 때문에 보통 var 키워드로 간단히 표현합니다.

foreach (KeyValuePair<string, int> pair in scoreTable)
{
    Console.WriteLine("Key: " + pair.Key);
    Console.WriteLine("Value: " + pair.Value);
}

또는 간단히

foreach (var pair in scoreTable)
{
    Console.WriteLine("Key: " + pair.Key);
    Console.WriteLine("Value: " + pair.Value);
}

 

Dictionary 를 활용한 등록, 조회, 값 수정

foreach() 는 순회 중에 컬렉션의 크기가 변해서는 안됩니다. 즉, foreach() 내부에서 Add(), Remove() 같은 함수를 쓰면 오류가 발생합니다. 그러나 값 자체의 수정은 문제되지 않습니다. 따라서 fruitPrices[key] = value + 100 처럼 인덱서를 이용해 값을 변경하는 코드는 가능하며 위험하지도 않습니다. 

// 과일 이름과 가격 등록
Dictionary<string, int> fruitPrices = new Dictionary<string, int>()
{
    { "사과", 1500 },
    { "바나나", 1200 },
    { "오렌지", 1800 },
    { "포도", 2000 }
    { "딸기", 3000 }
};

Console.WriteLine("[가격 인상 전]");
foreach (var pair in fruitPrices)
{
    Console.WriteLine($"{pair.Key} : {pair.Value}원");
}

// foreach 순회 중에는 key/value 추가나 삭제는 불가능하지만,
// 인덱서를 이용한 값 수정은 가능합니다.
foreach (var pair in fruitPrices)
{
    fruitPrices[pair.Key] = pair.Value + 100;
}

Console.WriteLine("\n[가격 인상 후]");
foreach (var pair in fruitPrices)
{
    Console.WriteLine($"{pair.Key} : {pair.Value}원");
}

 

정리

이처럼 Dictionary는 키(Key) 만 알면 원하는 값을 빠르게 찾을 수 있는 매우 강력한 자료구조입니다.
사용법도 간단하지만, 인덱서 ( [ ] ) 방식과 TryGetValue() 의 차이, Add()와 [ ] 의 동작 차이처럼 기본적인 원리를 잘 이해하고 사용하는 것이 중요합니다.