📚
【Python】競プロで使えるかもしれない小ネタ5選(Array編)
1.リストをシフトしながら循環させる
nums = [1,2,3,4,5]
l = len(nums)
print(nums) # [1, 2, 3, 4, 5]
"""
{特定のインデックス} % l によってインデックスの範囲が 0~l-1 の範囲に収まる
ことを利用してリストを循環させます。
"""
for i in range(l - 1):
print([nums[(i + j) % l] for j in range(1, l + 1)])
"""
[2, 3, 4, 5, 1]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
[5, 1, 2, 3, 4]
"""
"""
逆回しは以下の通り
"""
for i in range(1, l):
print([nums[(j - i) % l] for j in range(l)])
"""
[5, 1, 2, 3, 4]
[4, 5, 1, 2, 3]
[3, 4, 5, 1, 2]
[2, 3, 4, 5, 1]
"""
"""
よりPythonic(?)な感じ。こっちの方が速い。
"""
# 左にシフト
for i in range(1, length):
print(nums[i:] + nums[:i])
"""
[2, 3, 4, 5, 1]
[3, 4, 5, 1, 2]
[4, 5, 1, 2, 3]
[5, 1, 2, 3, 4]
"""
# 右にシフト
for j in range(1, length):
print( nums[-j:] + nums[:-j])
"""
[5, 1, 2, 3, 4]
[4, 5, 1, 2, 3]
[3, 4, 5, 1, 2]
[2, 3, 4, 5, 1]
"""
2.リスト間で重複している値を取得する
# setに変換してから論理積をとる
list1 = [1, 2, 3, 4, 5]
list2 = [3, 4, 5, 6, 7]
print(set(list1) & set(list2))
"""
{3, 4, 5}
"""
# setにすると重複した値が消えてしまうので、重複分も併せて取りたい場合は
# 内包表記等を使って取得する。
list1 = [1, 2, 2, 3, 4, 4, 5]
list2 = [3, 4, 4, 5, 6, 6, 7]
print([i for i in list1 if i in list2])
"""
[3, 4, 4, 5]
"""
3.リスト内の数値を結合して1つの数値を作る
list1 = ["1", "2", "3"]
# 合計を10倍して現在の値を加算する
ans = 0
for i in list1:
ans = ans * 10 + int(i)
print(ans) # 123
# 文字列でも同様だが、キャストしたほうがシンプル
str1 = "123"
ans = 0
for i in str1:
ans = ans * 10 + int(i)
print(ans) # 123
print(int(str1)) # 123
4.2次元リストの縦横並び替え
"""
[
[1,2,3],
[4,5,6],
[7,8,9]
]
↑を↓にする
[
[1,4,7],
[2,5,8],
[3,6,9]
]
"""
matrix = [[1,2,3], [4,5,6], [7,8,9]]
# zipはタプルを返すので、mapでリストに変換する
print(list(map(list,zip(*matrix)))) # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
# 上記は可読性が低いので以下でもいいんじゃないかなとは思う
columns = zip(*matrix)
for col in columns:
print(list(col))
"""
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]
"""
5.リスト内の0を後方へシフトする
"""
[1, 0, 2, 0, 3] -> [1, 2, 3, 0, 0]
"""
nums = [1, 0, 2, 0, 3]
# False=0, True=1 のため、lambda関数でFalseになる非0がリストの前方にくる
nums.sort(key=lambda x: x == 0)
print(nums) # 出力: [1, 2, 3, 0, 0]
Discussion