Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
961
Help us understand the problem. What are the problem?
Organization

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

本記事は、Fatos Morina氏による「100 Helpful Python Tips You Can Learn Before Finishing Your Morning Coffee」(2021年5月10日公開)の和訳を、著者の許可を得て掲載しているものです。

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


Photo by Jexo on Unsplash

はじめに

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

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

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

1. forループのelse条件

今までにPythonのあらゆるコードを見てきたとしても、次のfor-elseは見逃している可能性があります。私も数週間前に初めて見ました。

これはリストを繰り返すfor-elseメソッドで、リストを反復処理しているにもかかわらずelse条件もあるという、非常に珍しいものです。これは、JavaやRuby、JavaScriptなどの他のプログラミング言語では見られません。

実際にどのようなものか、例を見てみましょう。例えば、リストに奇数がないか調べているとします。リストを反復します。

numbers = [2, 4, 6, 8, 1]
for number in numbers:
    if number % 2 == 1:
        print(number)
        break
else:
    print("No odd numbers")

奇数が見つかった場合、breakを実行しelseブランチをスキップするため、その数字を出力します。それ以外はbreakを実行しないため、実行フローはelseブランチを実行します。

この例では、1を出力します。

2. 名前付き変数を使用して、リストから要素を取得する

my_list = [1, 2, 3, 4, 5]
one, two, three, four, five = my_list

3. heapqモジュールを使用して、リストの最大値または最小値からn個の要素を取得する

import heapq
scores = [51, 33, 64, 87, 91, 75, 15, 49, 33, 82]
print(heapq.nlargest(3, scores)) # [91, 87, 82]
print(heapq.nsmallest(5, scores)) # [15, 33, 33, 49, 51]

4. リストの値をメソッドの引数として渡す

リストのすべての要素を抽出するには、「*」を使用します。

my_list = [1, 2, 3, 4]
print(my_list) # [1, 2, 3, 4]
print(*my_list) # 1 2 3 4

これは、リストのすべての要素をメソッドの引数として渡す時に役立ちます。

def sum_of_elements(*arg):
    total = 0
    for i in arg:
        total += i
    return total
result = sum_of_elements(*[1, 2, 3, 4])
print(result) # 10

5. リストの中央にあるすべての要素を取得する

_, *elements_in_the_middle, _ = [1, 2, 3, 4, 5, 6, 7, 8]
print(elements_in_the_middle) # [2, 3, 4, 5, 6, 7]

6. 複数の変数に1行で代入する

one, two, three, four = 1, 2, 3, 4

7. リスト内包表記

内包表記を使用して、1行のコードでリストを繰り返します。例えば、リストの数値を2乗します。

numbers = [1, 2, 3, 4, 5]
squared_numbers = [num * num for num in numbers]
print(squared_numbers)

内包表記は、リストの操作だけではありません。辞書、集合、ジェネレータでも使用できます。

辞書内包表記を使用して、辞書の値を2乗する例を見てみましょう。

dictionary = {'a': 4, 'b': 5}
squared_dictionary = {key: num * num for (key, num) in dictionary.items()}
print(squared_dictionary) # {'a': 16, 'b': 25}

8. Enumを使用して、同じ概念の関連項目を列挙する

ドキュメントによると

Enumは、一意の値にバインドされた識別名の集合です。グローバル変数と似ていますが、より便利なrepr()やグループ化、型安全性などの機能があります。

例です。

from enum import Enum
class Status(Enum):
    NO_STATUS = -1
    NOT_STARTED = 0
    IN_PROGRESS = 1
    COMPLETED = 2
print(Status.IN_PROGRESS.name) # IN_PROGRESS
print(Status.COMPLETED.value) # 2

9. ループなしで文字列を繰り返す

name = "Banana"
print(name * 4) # BananaBananaBananaBanana

10. 数学のように3つの数字を比較する

ある値が他の2つの値の間にあるか比較したい場合、数学で使う簡単な式があります。

1 < x < 10

この式は、小学校で学ぶ代数式ですが、Pythonでも使えます。

そうです。今まで、このような形式の比較をしたことがあるでしょう。

1 < x and x < 10

Pythonでは、次のようにすればいいのです。

1 < x < 10

x = 3
print (1 < x < 10) # True

これは、プログラマを幸せにすることを目的に開発されたプログラミング言語であるRubyでは使えません。JavaScriptでは使えることが分かりました。

こんなに簡単な式があまり話題になっていないことに、本当に驚きました。少なくとも私は、話題になっているのをほとんど見たことがありません。

11. 辞書を読み取り可能な1行にマージする

これは、Python 3.9から利用可能です。

first_dictionary = {'name': 'Fatos', 'location': 'Munich'}
second_dictionary = {'name': 'Fatos', 'surname': 'Morina', 'location': 'Bavaria, Munich'}
result = first_dictionary | second_dictionary
print(result)
# {'name': 'Fatos', 'location': 'Bavaria, Munich', 'surname': 'Morina'}

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

books = ('Atomic habits', 'Ego is the enemy', 'Outliers', 'Mastery')
print(books.index('Mastery')) # 3

13. 文字列を文字列のリストに変換する

ある関数の入力が、リストであるべきところ文字列だったとします。

input = "[1,2,3]"

このような書式ではなく、リストにする必要があります。

input = [1,2,3]

または、API呼び出しから次のような応答があるかもしれません。

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

複雑な正規表現に煩わされずに、astモジュールをimportして、そのliteral_evalメソッドを呼び出すだけでよいのです。

import ast
def string_to_list(string):
    return ast.literal_eval(string)

それだけです。これで、次のようなリストまたはリストのリストとして結果を取得します。

import ast
def string_to_list(string):
    return ast.literal_eval(string)

string = "[[1, 2, 3],[4, 5, 6]]"
my_list = string_to_list(string)
print(my_list) # [[1, 2, 3], [4, 5, 6]]

14. 名前付きパラメータを使用して、凡ミスを防ぐ

2つの数値の差を計算するとします。差は非可換です。

a - b != b -a

しかし、パラメータの順序を忘れてしまうと、凡ミスをすることがあります。

def subtract(a, b):
   return a - b
print((subtract(1, 3))) # -2
print((subtract(3, 1))) # 2

このような潜在的なミスを避けるためには、名前付きのパラメータを使用するだけでよく、パラメータの順序はもはや問題ではなくなります。

def subtract(a, b):
    return a - b
print((subtract(a=1, b=3))) # -2
print((subtract(b=3, a=1))) # -2

15. 複数の要素を1つのprint()文で出力する

print(1, 2, 3, "a", "z", "this is here", "here is something else")

16. 複数の要素を1行で出力する

print("Hello", end="")
print("World") # HelloWorld
print("Hello", end=" ")
print("World") # Hello World
print('words', 'with', 'commas', 'in', 'between', sep=', ')
# words, with, commas, in, between

17. カスタム区切りを挿入した複数の値を出力する

高度な出力を簡単に行うことができます。

print("29", "01", "2022", sep="/") # 29/01/2022
print("name", "domain.com", sep="@") # name@domain.com

18. 変数名の先頭に数字を使用できない

four_letters = "abcd" # this works
4_letters = "abcd" # this doesn't work

19. 変数名の先頭に演算子を使用できない

+variable = "abcd" # this doesn't work

20. 数値の最初の桁に0を使用できない

number = 0110 # this doesn't work

21. 変数名のどこにでもアンダースコアを使用できる

変数名のどこにでも、何回でも、使えるということです。

a______b = "abcd" # this works
_a_b_c_d = "abcd" # this also works

使うことを推奨している訳ではありませんが、このような変な変数名を見かけた場合は、実際に有効な変数名であることを知っておいてください。

22. アンダースコアを使用して、大きな数字を区切る

これにより、より読みやすくなります。

print(1_000_000_000) # 1000000000
print(1_234_567) # 1234567

23. リストの順序を反転する

my_list = ['a', 'b', 'c', 'd']
my_list.reverse()
print(my_list) # ['d', 'c', 'b', 'a']

24. ステップ関数を使用して、文字列をスライスする

my_string = "This is just a sentence"
print(my_string[0:5]) # This

# Take three steps forward
print(my_string[0:10:3]) # Tssu

25. スライスを反転する

my_string = "This is just a sentence"
print(my_string[10:0:-1]) # suj si sih

# Take two steps forward
print(my_string[10:0:-2]) # sjs i

26. 開始または終了インデックスだけを使用して、部分スライスする

スライスの開始と終了を示すインデックスはオプションです。

my_string = "This is just a sentence"
print(my_string[4:]) # is just a sentence
print(my_string[:3]) # Thi

27. フロア分割

print(3/2) # 1.5
print(3//2) # 1

28. 「==」と「is」の違い

「is」は、2つの変数がメモリ内の同じオブジェクトを指しているか調べます。

「==」は、2つのオブジェクトが保持する値の同一性を比較します。

first_list = [1, 2, 3]
second_list = [1, 2, 3]

# Is their actual value the same?
print(first_list == second_list) # True

# Are they pointing to the same object in memory
print(first_list is second_list)
# False, since they have same values, but in different objects in
memory

third_list = first_list
print(third_list is first_list)
# True, since both point to the same object in memory

29. 2つの辞書を簡単にマージする

dictionary_one = {"a": 1, "b": 2}
dictionary_two = {"c": 3, "d": 4}
merged = {**dictionary_one, **dictionary_two}
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

30. 文字列が別の文字列よりも大きいか調べる

first = "abc"
second = "def"
print(first < second) # True
second = "ab"
print(first < second) # False

31. インデックス0を使用せずに、文字列が特定の文字で始まるか調べる

my_string = "abcdef"
print(my_string.startswith("b")) # False

32. id()を使用して、変数の一意のIDを取得する

print(id(1)) # 4325776624
print(id(2)) # 4325776656
print(id("string")) # 4327978288

33. 整数、浮動小数点数、文字列、ブール、タプルは不変である

整数、浮動小数点数、文字列、ブール、タプルなどの不変型に変数を代入すると、その変数はメモリ内のオブジェクトを指します。

その変数に別の値を代入した場合、元のオブジェクトはまだメモリ内に残っていますが、それを指す変数は失われます。

number = 1
print(id(number)) # 4325215472
print(id(1)) # 4325215472

number = 3
print(id(number)) # 4325215536
print(id(1)) # 4325215472

34. 文字列とタプルは不変である

既出ですが、非常に重要なので強調したいと思います。

name = "Fatos"
print(id(name)) # 4422282544

name = "fatos"
print(id(name)) # 4422346608
my_tuple = (1, 2, 3, 4)
print(id(my_tuple)) # 4499290128

my_tuple = ('a', 'b')
print(id(my_tuple)) # 4498867584

35. リスト、集合、辞書は可変である

オブジェクトへのバインドを失わずに、オブジェクトを変更できます。

cities = ["Munich", "Zurich", "London"]
print(id(cities)) # 4482699712

cities.append("Berlin")
print(id(cities)) # 4482699712

集合を使用する例です。

my_set = {1, 2, 3, 4}
print(id(my_set)) # 4352726176

my_set.add(5)
print(id(my_set)) # 4352726176

36. 集合を不変集合に変換する

これにより、変更できなくなります。

my_set = frozenset(['a', 'b', 'c', 'd'])
my_set.add("a")

これにより、エラーが発生します。

AttributeError: 'frozenset' object has no attribute 'add'

37. if-elifブロックは、最後にelseブロックがなくてもよい

ただし、elifはその前にifステップが必要です。

def check_number(number):
if number > 0:
return "Positive"
elif number == 0:
return "Zero"
return "Negative"
print(check_number(1)) # Positive

38. sorted()を使用して、2つの文字列がアナグラムか調べる

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

39. Unicodeで文字の値を取得する

print(ord("A")) # 65
print(ord("B")) # 66
print(ord("C")) # 66
print(ord("a")) # 97

40. 辞書のキーを1行で取得する

dictionary = {"a": 1, "b": 2, "c": 3}
keys = dictionary.keys()
print(list(keys)) # ['a', 'b', 'c']

41. 辞書の値を1行で取得する

dictionary = {"a": 1, "b": 2, "c": 3}
values = dictionary.values()
print(list(values)) # [1, 2, 3]

42. 辞書のキーと値を入れ替える

dictionary = {"a": 1, "b": 2, "c": 3}
reversed_dictionary = {j: i for i, j in dictionary.items()}
print(reversed) # {1: 'a', 2: 'b', 3: 'c'}

43. ブール値を数値に変換する

print(int(False)) # 0
print(float(True)) # 1.0

44. 算術演算でブール値を使用する

Falseは0、Trueは1です。

x = 10
y = 12
result = (x - False)/(y * True)
print(result) # 0.8333333333333334

45. データ型をブール値に変換する

print(bool(.0)) # False
print(bool(3)) # True
print(bool("-")) # True
print(bool("string")) # True
print(bool(" ")) # True

46. 値を複素数に変換する

print(complex(10, 2)) # (10+2j)
print(hex(11)) # 0xb

47. リストの先頭に値を追加する

append()を使用して、右から新しい値を挿入します。

insert()を使用して、新しい要素を挿入するインデックスと要素を指定できます。この場合は、先頭に挿入するため、インデックスは0を使用します。

my_list = [3, 4, 5]
my_list.append(6)
my_list.insert(0, 2)
print(my_list) # [2, 3, 4, 5, 6]

48. lambda関数は1行でしか記述できない

lambda関数は複数行で記述できません。

次のようにしてみましょう。

comparison = lambda x: if x > 3:
    print("x > 3")
else:
    print("x is not greater than 3")

次のエラーが発生します。

result = lambda x: if x > 3:
^
SyntaxError: invalid syntax

49. lambdaの条件文にはelse部が必須である

次のようにしてみましょう。

comparison = lambda x: "x > 3" if x > 3

次のエラーが発生します。

comparison = lambda x: "x > 3" if x > 3
^
SyntaxError: invalid syntax

なお、これは条件式の機能であり、lambda 自体の機能ではありません。


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

朝飯前に学べる!便利なPythonのヒント100選【後編】」もご覧ください。

翻訳協力

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

Original Author: Fatos Morina (https://www.linkedin.com/in/fatosimorina/)
Original Article: 100 Helpful Python Tips You Can Learn Before Finishing Your Morning Coffee
Thank you for letting us share your knowledge!

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

こちらもどうぞ
最近見つけたクールなPythonライブラリ6選
Python開発者のためのクールなPythonプロジェクト案10選

ご意見・ご感想をお待ちしております

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
961
Help us understand the problem. What are the problem?