상세 컨텐츠

본문 제목

list

Python

by techbard 2025. 4. 3. 07:34

본문

반응형

 

empty_list = [] # 빈 리스트를 만든다.
print(type(empty_list)) # 리스트인가?
# 결과
<class 'list'>

print(len(empty_list)) # 방금 생성한 리스트에는 아무것도 들어있지 않다.
# 결과
0

list_is_Container = []
list_is_Container[0:1] = '1' # 리스트의 첫째 자리에 1이라는 스트링을 넣는다.
print(list_is_Container)
# 결과
['1']

one_list = []
another_list = [2]
one_list.append(another_list) # 리스트 안에 또 다른 리스트를 넣는다.
print(one_list)
# 결과
[[2]]

 

# 리스트 요소의 삭제

planets = ['pluto', 'mars', 'earth', 'venus']
del planets[0] # 원본 리스트에서 삭제하는 방법 #1
print(planets)

print('')

planets = ['pluto', 'mars', 'earth', 'venus']
planets.remove('pluto') # 원본 리스트에서 삭제하는 방법 #2
print(planets)

# ==> del은 index 요소로 삭제 / remove 메서드는 요소 이름으로 삭제

# 결과
['mars', 'earth', 'venus']

['mars', 'earth', 'venus']
  • 리스트의 할당과 복사
def main():

    l1 = [1, 2, 3]
    l2 = l1

    # 두 객체는 같은 객체이다.
    print('addr of id1: ', id(l1))
    print('addr of id2: ', id(l2))
    if id(l1) == id(l2):
        print('[l1 is l2] - same object')
    else:
        print('[l1 is not l2]')

    print('\t')

    one = list(range(1, 4))
    another = one.copy()

    # 두 객체는 다른 객체이다.
    print('addr of one: ', id(one))
    print('addr of another: ', id(another))
    if id(one) == id(another):
        print('[one is another]')
    else:
        print('[one is not another] - diff. object')

    pass

if __name__ == '__main__':
    main()

# 결과

addr of id1:  2531229270592
addr of id2:  2531229270592
[l1 is l2] - same object
	
addr of one:  2531230033536
addr of another:  2531229270208
[one is not another] - diff. object

 

# deep copy (cf. shallow copy)
# mutable 객체는 복사에 레퍼런스 참조 사용
# 객체를 직접 복사하려면 copy 모듈 사용
import copy

org_list = [1, 1, 1]
cpy_list = copy.deepcopy(org_list)

print(f'original list: {org_list}')
print(f'copied list: {cpy_list}')

cpy_list[0] = 0
print(f'still original list: {org_list}')
print(f'modify copied list: {cpy_list}')

# 결과
original list: [1, 1, 1]
copied list: [1, 1, 1]
still original list: [1, 1, 1]
modify copied list: [0, 1, 1]

 

# 중첩 리스트의 인덱싱
nested_list = [[1, 2, 3], ['x', 'y'], ['apple', 'banana']]

print("before: ", end='')
print(f'{nested_list}, length: {len(nested_list)}')

nested_list[0].append(4)
nested_list[1].append('z')
nested_list[2].append('cherry')

print("after: ", end='')
print(f'{nested_list}, length: {len(nested_list)}')

# 각 내부 리스트에 요소를 추가했지만 내부 리스트 전체 개수의 변화는 없다.
before: [[1, 2, 3], ['x', 'y'], ['apple', 'banana']], length: 3
after: [[1, 2, 3, 4], ['x', 'y', 'z'], ['apple', 'banana', 'cherry']], length: 3

 

# 리스트의 더블 인덱싱
in_list = [1, 2, 3]
l = []

for i in range(len(in_list)):
    l.append(in_list[i])

print(l)

print([1, 2, 3][0], end=' ')
print([1, 2, 3][1], end=' ')
print([1, 2, 3][2])

# 결과
[1, 2, 3]
1 2 3

 

# 중첩 리스트의 변경
nested_list = [[1, 2, 3], ['x', 'y'], ['apple', 'banana']]

nested_list[1] = ['x', 'y', 'z']
nested_list[2][1] = 'cherry'

print(nested_list)

# 결과
[[1, 2, 3], ['x', 'y', 'z'], ['apple', 'cherry']]

 

# 연속 중첩 리스트의 인덱싱
data_list = ['a', [1, 2, []], [['apple', 'banana'], 'cherry']]

fruits = data_list[2][0][0]

print(fruits)

# 결과
apple

 

# 중첩 리스트를 가지고 kv dict를 생성해 데이터 정리
# isinstance(x, (int, float, complex)) and not isinstance(x, bool)

key_data = ['nums', 'alphas', 'fruits']
nl_dict = { k : [] for k in key_data} # {'nums': [], 'alphas': [], 'fruits': []}

nested_list = [[1, 2, 3], ['x', 'y', 'z'], ['apple', 'cherry']]

for nl in nested_list:
    if isinstance(nl[0], int):
        nl_dict['nums'] = nl
    elif isinstance(nl[0], str) and len(nl[0]) == 1:
        nl_dict['alphas'] = nl
    else:
        nl_dict['fruits'] = nl

print(nl_dict)

# 결과
{'nums': [1, 2, 3], 'alphas': ['x', 'y', 'z'], 'fruits': ['apple', 'cherry']}

 

# Nested Iteration
info = [['1', 10], ['2', 20], ['3', 30]]

values = []

for vl in info:
    values.append(vl[1])

print(values)

# 결과
[10, 20, 30]

 

# Having this mixture is going to make it hard to traverse
# the Nested Data structure.
# (TypeError: 'int' object is not itrerable.)
#
# The solution when we are in control of the data structure
# is to make it very regular with always the same kinds of items
# in the same level of nesting.
# In other words, dont mix integers, lists and dictionaries as items
# in a single list.
#
# Sometimes however, we arent in control of the data structure.

mixture_of_nested_list = [1, 2, ['a', 'b'], ['c'], ['d', 'e', 'f']]

for e in mixture_of_nested_list:
    print("level1: ")
    if type(e) is list:
        print(f"\tlevel2: {e}")
    else:
        print(e)

# 결과
level1: 
1
level1: 
2
level1: 
	level2: ['a', 'b']
level1: 
	level2: ['c']
level1: 
	level2: ['d', 'e', 'f']

 

# shallow copy
original = [[1, 2], ['1', '2']]
copied1 = original
copied2 = original[:]

print(f"Is copied1 equals original? {copied1 is original}")
print(f"Is copied2 equals original? {copied2 is original}")
print("")

original.append([3])

print(f"Now original is {original}")
print(f"Now copied1 is {copied1}")
print(f"Now copied2 is {copied2}")
print("")
# shallow copy (= copied2)는 추가 요소에 대해서는 구별되나
# 기존 요소는 copied1 = copied2 이다.

# 그러면 기존 요소를 바꾸는 경우 두 개가 달라질까?
# 먼저 리스트 요소 자체를 바꾸는 경우
del original[-1]
copied1[0] = ['x']

print(copied1)
print(copied2)
print("")
# ==> 정상이다.

# 그러면 리스트 내의 요소를 바꾸는 경우
copied1 = original
copied2 = original[:]

copied1[0][0] = 'x'
print(copied1)
print(copied2)
# => 안된다. 리스트 요소를 바꾸는 경우 두 객체가 같아지는 문제가 있고, 이것이 shallow copy의 문제이다.

# 결과
Is copied1 equals original? True
Is copied2 equals original? False

Now original is [[1, 2], ['1', '2'], [3]]
Now copied1 is [[1, 2], ['1', '2'], [3]]
Now copied2 is [[1, 2], ['1', '2']]

[['x'], ['1', '2']]
[[1, 2], ['1', '2']]

[['x'], ['1', '2']]
[['x'], ['1', '2']]

 

# list null check

empty_list = []

if not empty_list: # The pretty simple pythonic way.
    print("[1] null list")

if len(empty_list) == 0: # A much explicit way.
    print("[2] null list")

if empty_list == []: # Comparing it to an anonymous empty list.
    print("[3] null list")

if not bool(empty_list): # less readable surely
    print("[4] null list")

# 결과
[1] null list
[2] null list
[3] null list
[4] null list

 

# Reverse the list

ll = [list(), [1], 100]
print(f"original list: {ll}")

reversed_list_by_slice = ll[::-1]
print(f"reversed_list_by_slice: {reversed_list_by_slice}")

ll.reverse()
print(f"reversed_list_by_fx: {ll}")
# sort, sorted의 예를 보듯이
# 함수는 리턴을 하고, 메서드는 리턴을 하지 않고 해당 인스턴스를 변경한다.

# 결과
original list: [[], [1], 100]
reversed_list_by_slice: [100, [1], []]
reversed_list_by_fx: [100, [1], []]

 

# Confirm that the ojects are the same with the id function

list1 = [1, 2, 3]
list2 = list1

list3 = [1, 2, 3]

print(f"id(list1) == id(list2): {id(list1) == id(list2)}")
print(f"list1 is list2: {list1 is list2}")
print(f"list1 == list3: {list1 == list3}", end=' ')
print("* list1 and list3 are different object, but have same values.")

# 결과
id(list1) == id(list2): True
list1 is list2: True
list1 == list3: True * list1 and list3 are different object, but have same values.

 

lst_idx = [1, 2, 3]
lst_idx_len = len(lst_idx)

idx = 0
for idx in range(len(lst_idx)):
    out = lst_idx.pop(0)
    print(f"{out} is popped.")
    idx += 1
    # index로 돌며 무조건 1st를 pop하는 경우는 원하는대로 된다.

print("")

lst_in = [1, 2, 3]

for e in lst_in:
    out = lst_in.pop(0)
    print(f"{out} is popped.")
    # 이건 stop이 변하기 때문에 원하는 결과가 나오지 않는다.

# 결과
1 is popped.
2 is popped.
3 is popped.

1 is popped.
2 is popped.

 

# 리스트 안의 int를 int형으로 변환하기

number: list[int] = [1]

# 리스트 내 int를 int형으로 변환 방법 1
for num in number:
    print(type(num), num)

# 리스트 내 int를 int형으로 변환 방법 2
int_result = int(''.join(map(str, number)))
print(type(int_result), int_result)

# 리스트 내 int를 int형으로 변환 방법 3
ints = int(''.join(str(n) for n in number))
print(type(ints), ints)

# 결과
<class 'int'> 1
<class 'int'> 1
<class 'int'> 1

 

# If you're looping through a list, a good rule of thumb is to
# never modify that list while you're looping through it,
# because it will often lead to unwanted or unexpected behavior
# in your program.
# And in general, you will always want to use a temporary list
# if you decide to make any changes while you're looping through
# the original list, and then transfer the changes from that
# temporary list to the original.

# 간략히 말하면 list 중 요소를 제거하고 싶으면
# looping 중인 list를 변경(제거)하지 말고, 그것을 제외한 나머지를 새로운 list에
# 담는 방식으로 구현하자.

 

# string 처리가 복잡할 때는 list로 변환해서
# 가공 후에 다시 텍스트로 바꾸는 방법도 쉽다.
from string import whitespace, punctuation

title: str = "Section 5: Rewriting an Immutable String"
title_list: list[str] = list(title)
colon_position: int = title_list.index(':')
del title_list[:colon_position+1]

for i in range(len(title_list)):
    if title_list[i] in whitespace+punctuation:
        title_list[i] = '_'

title: str = ''.join(title_list)
print(title)
title = 'prefix' + title
print(title)

# 결과
_Rewriting_an_Immutable_String
prefix_Rewriting_an_Immutable_String

 

# 임의로 리스트 데이터를 가공하는 구현
person_marks: list[str, int] = \
[
    ['Bob', 75],
    ['Sally', 83],
    ['John', 91],
    ['Dave', 77]
]

marks_avg: int = sum([mark for (person, mark) in person_marks]) / len(person_marks)
print("=====" * 5)
print(f"marks avg: {marks_avg}")
print("=====" * 5)
person_marks_evaluation: dict[str, list[int, float]] = \
{person: [mark, "above avg or equal" if mark >= marks_avg else "below avg"] for (person, mark) in person_marks}
for (person, markeval) in person_marks_evaluation.items():
    print(f"{person:<5}, mark:{markeval[0]}, eval:{markeval[1]}")

# 결과
=========================
marks avg: 81.5
=========================
Bob  , mark:75, eval:below avg
Sally, mark:83, eval:above avg or equal
John , mark:91, eval:above avg or equal
Dave , mark:77, eval:below avg

 

# The valueof None is equivalent to "null" in other languages.
# The following values are falsy:
#   - None, 0, False, Empty sequence or mapping, Zero-length String

nums: list[int] = [1, 2, 3, 4, 5]
nums_stats: dict[str, int|float] = {'sum': 0, 'min': 0, 'max': 0, 'avg': 0, 'len': 0}

nums_sum: int = sum(nums)
nums_max: int = max(nums)
nums_min: int = min(nums)
nums_len: int = len(nums)
nums_avg: float = round(nums_sum/nums_len, 2)

nums_stats['avg'] = nums_avg
nums_stats['len'] = nums_len
nums_stats['max'] = nums_max
nums_stats['min'] = nums_min
nums_stats['sum'] = nums_sum

print(f"{nums_stats=}")

# 결과
nums_stats={'sum': 15, 'min': 1, 'max': 5, 'avg': 3.0, 'len': 5}

 

# find longest name (색다르게 구현한 버전)
names: list[str] = ['Cecilia', 'Lise', 'Marie']
names_sorted: list[str] = sorted(names, key=lambda name: len(name), reverse=True)
print(f"longest name: {names_sorted[0]}, len: {len(names_sorted[0])}")

# 결과
longest name: Cecilia, len: 7

 

# 랜덤으로 숫자와 알파벳을 생성해 zip으로 묶고
# dict를 조회하며 min, max, sum, avg 추출

import random
# 97 - 122, min, max, sum, avg

nums: list[int] = random.choices(range(100), k=10)
chrs: list[str] = list(map(chr, random.choices(range(97, 123), k=10)))
num_chr_pairs: dict[str, int] = {chr: num for chr, num in list(zip(chrs, nums))}

def get_avg(d: dict[str, int]) -> float:
    keys: list[str] = list(d.keys())
    total: int = sum([d[k]for k in keys])
    return round(total/len(keys), 2)

# 결과
{'p': 11, 'm': 57, 's': 86, 'u': 21, 'l': 99, 'd': 59}
min key: p, min value: 11
max key: l, max value: 99
sum: 333
avg: 55.5

def get_sum(d: dict[str, int]) -> int:
    keys: list[str] = list(d.keys())
    return sum([d[k]for k in keys])

def get_max(d: dict[str, int]) -> str:
    keys: list[str] = list(d.keys())
    max_key: str = keys[0]

    for k, v in d.items():
        if d[k] >= d[max_key]:
            max_key = k
    return max_key

def get_min(d: dict[str, int]) -> str:
    keys: list[str] = list(d.keys())
    min_key: str = keys[0]

    for k, v in d.items():
        if d[k] <= d[min_key]:
            min_key = k
    return min_key

print(num_chr_pairs)
min_key: str = get_min(num_chr_pairs)
print(f"min key: {min_key}, min value: {num_chr_pairs[min_key]}")

max_key: str = get_max(num_chr_pairs)
print(f"max key: {max_key}, max value: {num_chr_pairs[max_key]}")

sum_keys: str = get_sum(num_chr_pairs)
print(f"sum: {sum_keys}")

avg_keys: str = get_avg(num_chr_pairs)
print(f"avg: {avg_keys}")

 

# To access a member of a sequence type, use []

text: str = "hello"
list_str: list[str] = ['Bob', 'Sally', 'John']

extract_first_two: slice = slice(None, 2)

print(text[extract_first_two])
print(list_str[extract_first_two])

# 결과
he
['Bob', 'Sally']

 

# 조회하는 리스트에서 요소를 제거할 경우
# 조회 대상 자체가 변경되기 때문에 원하는 결과가 나오지 않는다.

# 회피 방법 #1
nums = [1, 2, 3, 4, 5]
pos = 0
result = []

while pos != len(nums):
    n = nums[pos]
    if n % 2 == 0:
        result.append(n)
    nums.remove(nums[0])

print(result)

# 회피 방법 #2 (제거하지 않고 index를 증가한다.)
nums = [1, 2, 3, 4, 5]
pos = 0
result = []

while pos < len(nums):
    if nums[pos] % 2 == 0:
        result.append(nums[pos])
    pos += 1

print(result)

# 결과
[2, 4]
[2, 4]

 

# Count the X's in a matrix

matrix = [["X", "O", "O"], ["O", "X", "O"], ["O", "O", "X"]]
flat = [item for sublist in matrix for item in sublist]
count_of_x = flat.count("X")
print(f"{count_of_x=}")

# 결과
count_of_x=3

 

data = [4, 5, 104, 105, 110, 120, 130, 130, 150,
        160, 170, 183, 185, 187, 188, 191, 350, 360]

min_valid = 100
max_valid = 200
result = [d for d in data if min_valid < d < max_valid]
print(result)

# 또 다른 방법: 인덱스를 얻어 원 데이터에서 삭제하는 방법
# 그러나, 이렇게 하면 안 된다. 의도한 결과가 나오지 않음
# 즉, target 데이터를 조회하며 제거할 때는 원본을 건드리지 말고
# 또 다른 리스트를 생성하는 것이 올바른 방법이다.

for idx, d in enumerate(data):
    if (d < min_valid) or (d > max_valid):
        del data[idx]
print(data)

# Output:
[104, 105, 110, 120, 130, 130, 150, 160, 170, 183, 185, 187, 188, 191]
[5, 104, 105, 110, 120, 130, 130, 150, 160, 170, 183, 185, 187, 188, 191, 360]

 

# Removing Items from a List Backwards (Safety Solution)
data = [104, 101, 4, 105, 308, 103, 5,
        107, 100, 306, 106, 102, 108]

min_valid = 100
max_valid = 200

print("Original:                    ", end='')
print(data)

for idx in range(len(data) - 1, -1, -1):
    if (data[idx] < min_valid) or (data[idx] > max_valid):
        del data[idx]

print("Safety removing of list item:", end='')
print(data)

# Output:
Original:                    [104, 101, 4, 105, 308, 103, 5, 107, 100, 306, 106, 102, 108]
Safety removing of list item:[104, 101, 105, 103, 107, 100, 106, 102, 108]

 

# another way of flatten list 

my_int_list = [[1, 2], [3, 4], [5, 6]]

# # 방법 1 - sum 함수
answer = sum(my_int_list, [])
print(answer)

my_str_list = [["apple", "banana"], ["cherry", "durian"]]
flat_list = sum(my_str_list, [])
print(flat_list)

# # 방법 2 - itertools.chain.from_iterable
import itertools
result = list(itertools.chain.from_iterable(my_str_list))
print(result)

# output
[1, 2, 3, 4, 5, 6]
['apple', 'banana', 'cherry', 'durian']
['apple', 'banana', 'cherry', 'durian']

 

# flatten list method #1

my_list = [["apple", "banana"], ["cherry"], ["durian", "elderberry"]]

flat_list_1 = sum(my_list, [])
print(flat_list_1)

# flatten list method #2
import itertools
flat_list_2 = itertools.chain.from_iterable(my_list)
print(list(flat_list_2))

# flatten list method #3
flat_list_3 = [inner for outer in my_list for inner in outer]
print(flat_list_3)

# output
['apple', 'banana', 'cherry', 'durian', 'elderberry']
['apple', 'banana', 'cherry', 'durian', 'elderberry']
['apple', 'banana', 'cherry', 'durian', 'elderberry']

 

# list 평탄화, 이종의 리스트를 한 개의 리스트로 변환

my_list = [["apple", "banana"], ["cherry"], "durian"]

### Using list conprehension
flat_list_using_comprehension = \
[inner for outer in my_list for inner in (outer if isinstance(outer, list) else [outer])]
print(flat_list_using_comprehension)

# output
['apple', 'banana', 'cherry', 'durian']

### Using sum(), 하지만 리스트가 요소가 모두 균일해야 한다.
for e in my_list:
    if isinstance(e, list):
        continue
    else:
        idx = my_list.index(e)
        my_list[idx] = [e]
flat_list_using_sum_func = sum(my_list, [])
print(flat_list_using_sum_func)

# output
['apple', 'banana', 'cherry', 'durian']

### Using for - in - list comprehension
### list index를 건드리는 건 위험할 수 있어서 별도의 리스트를 생성한다.
processed_list = []
for e in my_list:
    if isinstance(e, list):
        processed_list.extend(e)
    else:
        processed_list.append(e)
print(processed_list)

# output
['apple', 'banana', 'cherry', 'durian']

 

two_d_list = [["apple", "banana"], ["cherry"], "durian", "citrus"]

### Using for-in list comprehension for build flat_list
fruit_list = [inner for outer in two_d_list for inner in (outer if isinstance(outer, list) else [outer])]
print(fruit_list)

### Make fruit dict by first letter
group_alpha = {}
for fruit in fruit_list:
    key = fruit[0]
    (group_alpha.setdefault(key, [])).append(fruit)
print(group_alpha)

### output
['apple', 'banana', 'cherry', 'durian', 'citrus']
{'a': ['apple'], 'b': ['banana'], 'c': ['cherry', 'citrus'], 'd': ['durian']}

 

# make matrix to flat-list
two_d_fruits = [["apple", "banana"], ["cherry"], "durian", "cranberry"]

group_fruit = {}
fruits = [inner for outer in two_d_fruits for inner in (outer if isinstance(outer, list) else [outer])]

for fruit in fruits:
    key = fruit[0]
    (group_fruit.setdefault(key, [])).append(fruit)
# output
{'a': ['apple'], 'b': ['banana'], 'c': ['cherry', 'cranberry'], 'd': ['durian']}

# make fruits dict based on first letter and count them
for key in group_fruit:
    group_fruit[key].insert(0, f"len: {len(group_fruit[key])}")

print(group_fruit)

# output
{'a': ['len: 1', 'apple'], 'b': ['len: 1', 'banana'], 'c': ['len: 2', 'cherry', 'cranberry'], 'd': ['len: 1', 'durian']}
반응형

관련글 더보기

댓글 영역