朝飯前に学べる！便利なPythonのヒント100選【後編】

本記事は、[Fatos Morina](https://fatosmorina.medium.com/)氏による「[100 Helpful Python Tips You Can Learn Before Finishing Your Morning Coffee](https://towardsdatascience.com/100-helpful-python-tips-you-can-learn-before-finishing-your-morning-coffee-eb9c39e68958)」（2021年5月10日公開）の和訳を、著者の許可を得て掲載しているものです。

#朝飯前に学べる！便利なPythonのヒント100選【後編】

![](https://miro.medium.com/max/1400/0*ujQYo_bH_XCyvfF4)
Photo by [Jexo](https://unsplash.com/@jexo?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com/?utm_source=medium&utm_medium=referral)

##はじめに

Pythonは、主にそのシンプルさと習得のしやすさから、最近では非常に人気があります。

データサイエンスや機械学習、ウェブ開発、スクリプト記述、自動化など、幅広い分野で利用することができます。

この記事はかなり長いので、すぐ始めましょう。

##50. filter()は新しいオブジェクトを返す

```python
my_list = [1, 2, 3, 4]
odd = filter(lambda x: x % 2 == 1, my_list)
print(list(odd)) # [1, 3]
print(my_list) # [1, 2, 3, 4]
```

##51. map()は新しいオブジェクトを返す

```python
my_list = [1, 2, 3, 4]
squared = map(lambda x: x ** 2, my_list)
print(list(squared)) # [1, 4, 9, 16]
print(my_list) # [1, 2, 3, 4]
```

##52. range()にはあまり知られていないステップパラメータがある

```python
for number in range(1, 10, 3):
print(number, end=" ")
# 1 4 7
```

##53. range()はデフォルトで0から始まる

そのため、0を含める必要は全くありません。

```python
def range_with_zero(number):
    for i in range(0, number):
        print(i, end=' ')
def range_with_no_zero(number):
    for i in range(number):
        print(i, end=' ')

range_with_zero(3) # 0 1 2
range_with_no_zero(3) # 0 1 2
```

##54. 長さを0と比較する必要はない

長さが0より大きい場合、デフォルトでTrueなので、0と比較する必要はありません。

```python
def get_element_with_comparison(my_list):
    if len(my_list) > 0:
        return my_list[0]
def get_first_element(my_list):
    if len(my_list):
        return my_list[0]

elements = [1, 2, 3, 4]
first_result = get_element_with_comparison(elements)
second_result = get_element_with_comparison(elements)

print(first_result == second_result) # True
```

##55. 同じスコープで同じメソッドを複数回定義できる

ただし、前のものを上書きするため、最後のものだけが呼び出されます。

```python
def get_address():
    return "First address"
def get_address():
    return "Second address"
def get_address():
    return "Third address"

print(get_address()) # Third address
```

##56. 指定スコープ外のプライベートプロパティにもアクセスできる

```python
class Engineer:
    def __init__(self, name):
        self.name = name
        self.__starting_salary = 62000

dain = Engineer('Dain')
print(dain._Engineer__starting_salary) # 62000
```

##57. オブジェクトのメモリ使用量を調べる

```python
import sys
print(sys.getsizeof("bitcoin")) # 56
```

##58. パラメータを何個でも指定して呼び出せるメソッドを定義する

```python
def get_sum(*arguments):
    result = 0
    for i in arguments:
        result += i
    return result

print(get_sum(1, 2, 3)) # 6
print(get_sum(1, 2, 3, 4, 5)) # 15
print(get_sum(1, 2, 3, 4, 5, 6, 7)) # 28
```

##59. super()または親クラス名を使用して、親クラスのイニシャライザを呼び出す

super()を使用して、親クラスのイニシャライザを呼び出すことができます。

```python
class Parent:
    def __init__(self, city, address):
        self.city = city
        self.address = address
class Child(Parent):
    def __init__(self, city, address, university):
        super().__init__(city, address)
        self.university = university

child = Child('Zürich', 'Rämistrasse 101', 'ETH Zürich')
print(child.university) # ETH Zürich
```

親クラス名を使用して、親クラスを呼び出します。

```python
class Parent:
    def __init__(self, city, address):
        self.city = city
        self.address = address
class Child(Parent):
    def __init__(self, city, address, university):
        Parent.__init__(self, city, address)
        self.university = university

child = Child('Zürich', 'Rämistrasse 101', 'ETH Zürich')
print(child.university) # ETH Zürich
```

なお、**\_\_init__()**や**super()**を使用した親のイニシャライザの呼び出しは、子クラスのイニシャライザ内部だけで使用できます。

##60. 自クラスで「+」演算子を再定義する

2つの**整数**型で「+」演算子を使用すると、その和を取得します。

2つの**文字列**型で使用すると、それらをマージします。

```python
print(10 + 1) # Adding two integers using '+'
print('first' + 'second') # Merging two strings '+'
```

これが**演算子のオーバーロード**です。

自クラスでも使用できます。

```python
class Expenses:
    def __init__(self, rent, groceries):
        self.rent = rent
        self.groceries = groceries
    def __add__(self, other):
        return Expenses(self.rent + other.rent, self.groceries + other.groceries)

april_expenses = Expenses(1000, 200)
may_expenses = Expenses(1000, 300)

total_expenses = april_expenses + may_expenses
print(total_expenses.rent) # 2000
print(total_expenses.groceries) # 500
```

##61. 自クラスで「<」演算子および「==」演算子を再定義する

自分で定義できる演算子のオーバーロードの例です。

```python
class Game:
    def __init__(self, score):
        self.score = score
    def __lt__(self, other):
        return self.score < other.score

first = Game(1)
second = Game(2)

print(first < second) # True
```

先の2つと同じように、自分のニーズに基づいて、\_\_eq__()関数を上書きできます。

```python
class Journey:
    def __init__(self, location, destination, duration):
        self.location = location
        self.destination = destination
        self.duration = duration
    def __eq__(self, other):
        return ((self.location == other.location) and
                (self.destination == other.destination) and
                (self.duration == other.duration))

first = Journey('Location A', 'Destination A', '30min')
second = Journey('Location B', 'Destination B', '30min')

print(first == second)
```

次も同様に定義することもできます。

-   \_\_sub__() 「-」
-   \_\_mul__() 「*」
-   \_\_truediv__() 「/」
-   \_\_ne__() 「!=」
-   \_\_ge__() 「>=」
-   \_\_gt__() 「>」

##62. クラスのオブジェクトのカスタム印刷可能なバージョンを定義する

```python
class Rectangle:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __repr__(self):
        return repr('Rectangle with area=' + str(self.a * self.b))

print(Rectangle(3, 4)) # 'Rectangle with area=12'
```

##63. 文字列の文字の大文字と小文字を入れ替える

```python
string = "This is just a sentence."
result = string.swapcase()
print(result) # tHIS IS JUST A SENTENCE.
```

##64. 文字列のすべての文字が空白か調べる

```python
string = " "
result = string.isspace()
print(result) # True
```

##65. 文字列のすべての文字がアルファベットまたは数字か調べる

```python
name = "Password"
print(name.isalnum()) # True, because all characters are alphabets
name = "Secure Password "
print(name.isalnum()) # False, because it contains whitespaces
name = "S3cur3P4ssw0rd"
print(name.isalnum()) # True
name = "133"
print(name.isalnum()) # True, because all characters are numbers
```

##66. 文字列のすべての文字がアルファベットか調べる

```python
string = "Name"
print(string.isalpha()) # True
string = "Firstname Lastname"
print(string.isalpha()) # False, because it contains whitespace
string = "P4ssw0rd"
print(string.isalpha()) # False, because it contains numbers
```

##67. 引数に基づいて、右から文字を削除する

```python
string = "This is a sentence with "
# Remove trailing spaces from the right
print(string.rstrip()) # "This is a sentence with "
string = "this here is a sentence.....,,,,aaaaasd"
print(string.rstrip(".,dsa")) # "this here is a sentence"
```

同じように、引数に基づいて、左から文字を削除することもできます。

```python
string = "ffffffffFirst"
print(string.lstrip("f")) # First
```

##68. 文字列が数値か調べる

```python
string = "seven"
print(string.isdigit()) # False
string = "1337"
print(string.isdigit()) # True
string = "5a"
print(string.isdigit()) # False, because it contains the character 'a'
string = "2**5"
print(string.isdigit()) # False
```

##69. 文字列が漢数字か調べる

```python
# 42673 in Arabic numerals
string = "四二六七三"
print(string.isdigit()) # False
print(string.isnumeric()) # True
```

##70. 文字列のすべての単語が大文字で始まるか調べる

```python
string = "This is a sentence"
print(string.istitle()) # False
string = "10 Python Tips"
print(string.istitle()) # True
string = "How to Print A String in Python"
# False, because of the first characters being lowercase in "to" and "in"
print(string.istitle())
string = "PYTHON"
print(string.istitle()) # False. It's titlelized version is "Python"
```

##71. タプルでも負のインデックスを使用できる

```python
numbers = (1, 2, 3, 4)
print(numbers[-1]) # 4
print(numbers[-4]) # 1
```

##72. タプルにリストとタプルをネストする

```python
mixed_tuple = (("a"*10, 3, 4), ['first', 'second', 'third'])
print(mixed_tuple[1]) # ['first', 'second', 'third']
print(mixed_tuple[0]) # ('aaaaaaaaaa', 3, 4)
```

##73. リストに条件を満たす要素が出現する回数を簡単に数える

```python
names = ["Besim", "Albert", "Besim", "Fisnik", "Meriton"]
print(names.count("Besim")) # 2
```

##74. slice()を使用して、最後のn個の要素を簡単に取得する

```python
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
slicing = slice(-4, None)

# Getting the last 3 elements from the list
print(my_list[slicing]) # [4, 5, 6]

# Getting only the third element starting from the right
print(my_list[-3]) # 4
```

次のような通常のスライスタスクにもslice()を使用できます。

```python
string = "Data Science"

# start = 1, stop = None (don't stop anywhere), step = 1
# contains 1, 3 and 5 indices
slice_object = slice(5, None)

print(string[slice_object]) # Science
```

##75. タプルに要素が出現する回数を数える

```python
my_tuple = ('a', 1, 'f', 'a', 5, 'a')
print(my_tuple.count('a')) # 3
```

##76. タプルの要素のインデックスを取得する

```python
my_tuple = ('a', 1, 'f', 'a', 5, 'a')
print(my_tuple.index('f')) # 2
```

##77. ジャンプを使用してサブタプルを取得する

```python
my_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(my_tuple[::3]) # (1, 4, 7, 10)
```

##78. インデックスから始まるサブタプルを取得する

```python
my_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(my_tuple[3:]) # (4, 5, 6, 7, 8, 9, 10)
```

##79. リスト、集合、辞書からすべての要素を削除する

```python
my_list = [1, 2, 3, 4]
my_list.clear()
print(my_list) # []

my_set = {1, 2, 3}
my_set.clear()
print(my_set) # set()

my_dict = {"a": 1, "b": 2}
my_dict.clear()
print(my_dict) # {}
```

##80. 2つの集合を結合する

1つの方法は、union()メソッドを使用して、結合の結果として新しい集合を返します。

```python
first_set = {4, 5, 6}
second_set = {1, 2, 3}
print(first_set.union(second_set)) # {1, 2, 3, 4, 5, 6}
```

もう1つの方法は、update()メソッドを使用して、2 番目の集合の要素を 1
番目の集合に挿入します。

```python
first_set = {4, 5, 6}
second_set = {1, 2, 3}
first_set.update(second_set)
print(first_set) # {1, 2, 3, 4, 5, 6}
```

##81. print関数の条件

```python
def is_positive(number):
    print("Positive" if number > 0 else "Negative") # Positive
is_positive(-3)
```

##82. 1つのif文で複数条件を指定する

```python
math_points = 51
biology_points = 78
physics_points = 56
history_points = 72

my_conditions = [math_points > 50, biology_points > 50, physics_points > 50, history_points > 50]

if all(my_conditions):
    print("Congratulations! You have passed all of the exams.")
else:
    print("I am sorry, but it seems that you have to repeat at least one exam.")
# Congratulations! You have passed all of the exams.
```

##83. 1つのif文で、複数条件のうち少なくとも1つの条件を満たす

```python
math_points = 51
biology_points = 78
physics_points = 56
history_points = 72

my_conditions = [math_points > 50, biology_points > 50, physics_points > 50, history_points > 50]

if any(my_conditions):
    print("Congratulations! You have passed all of the exams.")
else:
    print("I am sorry, but it seems that you have to repeat at least one exam.")
# Congratulations! You have passed all of the exams.
```

##84. 空でない文字列をTrueと評価する

```python
print(bool("Non empty")) # True
print(bool("")) # False
```

##85. 空でないリスト、タプル、辞書をTrueと評価する

```python
print(bool([])) # False
print(bool(set([]))) # False

print(bool({})) # False
print(bool({"a": 1})) # True
```

##86. Falseと評価する値は、None、False、数値0である

```python
print(bool(False)) # False
print(bool(None)) # False
print(bool(0)) # False
```

##87. 関数で言及するだけでは、グローバル変数の値を変更できない

```python
string = "string"
def do_nothing():
    string = "inside a method"
do_nothing()
print(string) # string
```

アクセス修飾子 **global** も使用する必要があります。

```python
string = "string"
def do_nothing():
    global string
    string = "inside a method"
do_nothing()
print(string) # inside a method
```

##88. collectionsのCounterを使用して、文字列またはリストの要素数を数える

```python
from collections import Counter

result = Counter("Banana")
print(result) # Counter({'a': 3, 'n': 2, 'B': 1})

result = Counter([1, 2, 1, 3, 1, 4, 1, 5, 1, 6])
print(result) # Counter({1: 5, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1})
```

##89. Counter を使用して、2つの文字列がアナグラムか調べる

```python
from collections import Counter

def check_if_anagram(first_string, second_string):
    first_string = first_string.lower()
    second_string = second_string.lower()
    return Counter(first_string) == Counter(second_string)

print(check_if_anagram('testinG', 'Testing')) # True
print(check_if_anagram('Here', 'Rehe')) # True
print(check_if_anagram('Know', 'Now')) # False
```

sorted()を使用して、2つの文字列がアナグラムか調べることもできます。

```python
def check_if_anagram(first_word, second_word):
    first_word = first_word.lower()
    second_word = second_word.lower()
    return sorted(first_word) == sorted(second_word)

print(check_if_anagram("testinG", "Testing")) # True
print(check_if_anagram("Here", "Rehe")) # True
print(check_if_anagram("Know", "Now")) # False
```

##90. itertoolsのcountを使用して、要素数を数える

```python
from itertools import count
my_vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
current_counter = count()
string = "This is just a sentence."
for i in string:
    if i in my_vowels:
        print(f"Current vowel: {i}")
        print(f"Number of vowels found so far: {next(current_counter)}")
```

これがコンソールに出力される結果です。

```python
Current vowel: i
Number of vowels found so far: 0
Current vowel: i
Number of vowels found so far: 1
Current vowel: u
Number of vowels found so far: 2
Current vowel: a
Number of vowels found so far: 3
Current vowel: e
Number of vowels found so far: 4
Current vowel: e
Number of vowels found so far: 5
Current vowel: e
Number of vowels found so far: 6
```

##91. 頻度に基づいて、文字列またはリストの要素をソートする

collectionsモジュールのcounterは、デフォルトでは、頻度に基づいて要素をソートしません。

```python
from collections import Counter
result = Counter([1, 2, 3, 2, 2, 2, 2])
print(result) # Counter({2: 5, 1: 1, 3: 1})
print(result.most_common()) # [(2, 5), (1, 1), (3, 1)]
```

##92. リストで最も頻度の高い要素を1行で取得する

```python
my_list = ['1', 1, 0, 'a', 'b', 2, 'a', 'c', 'a']
print(max(set(my_list), key=my_list.count)) # a
```

##93. copy()とdeepcopy()の違い

ドキュメントの[説明](https://docs.python.org/3/library/copy.html#:~:text=A%20shallow%20copy%20constructs%20a,objects%20found%20in%20the%20original.)によると
>浅いコピーは、新しい複合オブジェクトを構築し、（可能な範囲で）元のオブジェクトへの参照を挿入します。
>深いコピーは、新しい複合オブジェクトを構築し、再帰的に、元のオブジェクトにあるオブジェクトのコピーを挿入します。

より包括的な説明は[こちら](https://realpython.com/copying-python-objects/)
>浅いコピーは、新しいコレクションオブジェクトを構築し、元のオブジェクトにある子オブジェクトへの参照を挿入することです。基本的に、浅いコピーは1レベルの深さしかありません。コピー処理は再帰的に行わないため、子オブジェクト自体のコピーを作成しません。
>深いコピーは、コピー処理を再帰的に行います。つまり、新しいコレクションオブジェクトを構築し、元のオブジェクトにある子オブジェクトのコピーを再帰的に挿入します。この方法でオブジェクトをコピーすると、オブジェクトツリー全体をウォークし、元のオブジェクトとそのすべての子オブジェクトの完全に独立したクローンを作成します。

copy()の例です。

```python
first_list = [[1, 2, 3], ['a', 'b', 'c']]
second_list = first_list.copy()
first_list[0][2] = 831

print(first_list) # [[1, 2, 831], ['a', 'b', 'c']]
print(second_list) # [[1, 2, 831], ['a', 'b', 'c']]
```

deepcopy()の例です。

```python
import copy

first_list = [[1, 2, 3], ['a', 'b', 'c']]
second_list = copy.deepcopy(first_list)
first_list[0][2] = 831

print(first_list) # [[1, 2, 831], ['a', 'b', 'c']]
print(second_list) # [[1, 2, 3], ['a', 'b', 'c']]
```

##94. 辞書で存在しないキーにアクセスしようとした時のエラー発生を防ぐ

通常の辞書を使用していて、存在しないキーにアクセスしようとすると、エラーが発生します。

```python
my_dictonary = {"name": "Name", "surname": "Surname"}
print(my_dictonary["age"])
```

送出されたエラーです。

```python
KeyError: 'age'
```

defaultdict()を使用して、このようなエラーを回避できます。

```python
from collections import defaultdict

my_dictonary = defaultdict(str)
my_dictonary['name'] = "Name"
my_dictonary['surname'] = "Surname"

print(my_dictonary["age"])
```

##95. 独自イテレータを構築する

```python
class OddNumbers:
    def __iter__(self):
        self.a = 1
        return self
    def __next__(self):
        x = self.a
        self.a += 2
        return x

odd_numbers_object = OddNumbers()
iterator = iter(odd_numbers_object)

print(next(iterator)) # 1
print(next(iterator)) # 3
print(next(iterator)) # 5
```

##96. リストの重複を1行で削除する

```python
my_set = set([1, 2, 1, 2, 3, 4, 5])
print(list(my_set)) # [1, 2, 3, 4, 5]
```

##97. モジュールの場所を出力する

```python
import torch
print(torch) # <module 'torch' from '/Users/...'
```

##98. not inを使用して、値がリストに含まれていないか調べる

```python
odd_numbers = [1, 3, 5, 7, 9]
even_numbers = []

for i in range(9):
    if i not in odd_numbers:
        even_numbers.append(i)

print(even_numbers) # [0, 2, 4, 6, 8]
```

##99. sort()とsorted()の違い

**sort()**は、元のリストをソートします。

**sorted()**は、ソートされた新しいリストを返します。

```python
groceries = ['milk', 'bread', 'tea']

new_groceries = sorted(groceries)
# new_groceries = ['bread', 'milk', 'tea']
print(new_groceries)

# groceries = ['milk', 'bread', 'tea']
print(groceries)

groceries.sort()
# groceries = ['bread', 'milk', 'tea']
print(groceries)
```

##100. uuidモジュールを使用して、一意のIDを生成する

UUIDとは、Universally Unique Identifierの略です。

```python
import uuid

# Generate a UUID from a host ID, sequence number, and the current time
print(uuid.uuid1()) # 308490b6-afe4-11eb-95f7-0c4de9a0c5af

# Generate a random UUID
print(uuid.uuid4()) # 93bc700b-253e-4081-a358-24b60591076a
```

##101. （おまけ）Pythonでは、文字列はプリミティブ型である

Java経験者なら、Javaでは文字列がオブジェクトを参照するため、非プリミティブ型であることを知っているでしょう。

Pythonでは、文字列はプリミティブ型です。

***

この記事がお役に立てれば幸いです。ハッピーコーディング！

「[朝飯前に学べる！便利なPythonのヒント100選【前編】](https://qiita.com/baby-degu/items/05cf809d4d992923020d)」もご覧ください。


##翻訳協力

この記事は以下の方々のご協力により公開する事ができました。改めて感謝致します。

Original Author: [Fatos Morina](https://fatosmorina.medium.com/) (<https://www.linkedin.com/in/fatosimorina/>)
Original Article: [100 Helpful Python Tips You Can Learn Before Finishing Your Morning Coffee](https://towardsdatascience.com/100-helpful-python-tips-you-can-learn-before-finishing-your-morning-coffee-eb9c39e68958)
Thank you for letting us share your knowledge!

選定担当: @gracen
翻訳担当: @gracen
監査担当: -
公開担当: @gracen

>**こちらもどうぞ**
>[最近見つけたクールなPythonライブラリ6選](https://qiita.com/baby-degu/items/86e8881d3317da17617c)
>[Python開発者のためのクールなPythonプロジェクト案10選](https://qiita.com/baby-degu/items/449afb3568925d281d6c)

##ご意見・ご感想をお待ちしております
今回の記事はいかがでしたか？
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
頂いたお声は、今後の記事の質向上に役立たせて頂きますので、お気軽に
コメント欄にてご投稿ください。[Twitter](https://twitter.com/BabyDegu?lang=ja)でもご意見を受け付けております。
皆様のメッセージをお待ちしております。