neverjpのぶらり日記

コンピューター関連の記事とぶらりと出かけた先の写真など

AIのシンギュラリティとは?(その2)

AIのシンギュラリティ


AIのシンギュラリティとは?

AIのシンギュラリティは、人工知能が人間の知能を超越し、自己進化を遂げ、人間の理解や制御を超えた段階を指します。これは未来の予測に基づく概念であり、議論の的となっています。

 

AIのシンギュラリティは、レイ・カーツワイルが提唱した概念で、人工知能が指数関数的に進化し、その進化が人間の理解を超越するというアイディアです。これが実現すると、AIは自己進化を続け、人間の知能や能力を超え、制御不能になる可能性があります。

 

シンギュラリティが現実化すると、AIは新たな技術や知識を爆発的に獲得し、複雑な問題に対処する能力が急速に向上します。これにより、社会や経済、倫理的な側面に大きな変革が生じる可能性があります。ただし、シンギュラリティの到来には不確実性が伴い、議論の余地が多いトピックです。

 

社会や経済、倫理的な側面に大きな変革が生じる可能性、どんな可能性がありますか?

AIのシンギュラリティが実現すれば、様々な社会的、経済的、および倫理的な変革が生じる可能性があります。以下に、その一部を挙げてみましょう:

 

労働市場の変化: シンギュラリティにより、多くの仕事が自動化され、従来の労働市場に大きな変化が生じる可能性があります。一方で、新たな職種や産業が生まれることも期待されます。

 

経済の再構築: 自己進化するAIが経済プロセスや意思決定に関与することで、効率性が向上し、新たな経済モデルが形成される可能性があります。しかし、その過程で格差が広がることや、既存の経済構造に対する挑戦も考えられます。

 

医療の進化: AIが医療診断や治療に使用され、個々の患者に合わせた効果的な治療法が開発される可能性があります。これにより、疾患の早期検出や治療の精度向上が期待されます。

 

倫理とプライバシーの問題: 進化するAIが個人のデータや情報を使用することで、プライバシーの懸念が浮上する可能性があります。倫理的な基準や法的な規制の必要性が増すかもしれません。

 

社会的な影響と課題: シンギュラリティの進展は、人間の社会構造や価値観にも影響を与えるでしょう。新たな倫理的・哲学的な問いが生まれ、社会がそれにどのように対応するかが求められます。

 

これらは予測に過ぎませんが、シンギュラリティが実現すれば、これらの変化が生じる可能性があり、それに対処するためには慎重な計画と国際的な協力が必要となるでしょう。

 

対処するためには慎重な計画と国際的な協力が必要、どんな計画や協力ですか?

シンギュラリティに対処するための計画や協力は非常に複雑であり、多くの異なる側面を考慮する必要があります。以下は、その一例です:

 

国際的な協力と規制の策定: シンギュラリティの影響は国を越えるものであるため、国際的な協力が必要です。国際的な規制やガイドラインの策定により、倫理的な標準や技術の進展に対処できます。

 

倫理的なフレームワークの確立: シンギュラリティに関連する倫理的な問題に対処するために、国際的な倫理的なフレームワークを確立することが重要です。これは、人権、プライバシー、公平性などに焦点を当てたものであるべきです。

 

教育とスキルのアップデート: シンギュラリティによる変化に対応するために、教育システムをアップデートし、新たなスキルや知識を身につけるための機会を提供する必要があります。これは、人々が変化に適応できるようにするための重要な要素です。

 

技術の透明性と説明責任: 進化するAIシステムが透明性を持ち、意思決定の過程が理解可能であることが求められます。また、開発者や企業はその技術の結果に責任を持つ必要があります。

 

社会的包摂と格差の是正: 技術の進化により労働市場が変化する場合、社会的な包摂を促進し、格差を是正するための政策が求められます。これには再教育プログラムや社会的なサポートの充実が含まれます。

 

リサーチと開発への投資: シンギュラリティに関するリサーチと開発への投資が必要です。これにより、技術の進展に追いつき、その進化を適切にガイドする手段が得られます。

 

これらの取り組みは協力を要するため、国際的な組織や国家間のパートナーシップが不可欠です。慎重な計画と継続的な協力によって、シンギュラリティに伴う変革に対処し、そのポジティブな側面を最大限に活かすことが期待されます。

 人気ブログランキングへ←人気ブログランキングに参加しています。ポチっと1票を!

 

VR端末

VRゴーグル(別製品)

VRゴーグル(読売新聞)



米IT大手Appleは8日、初めてとなる。仮想現実(VR)対応端末「アップ.ビジョン.プロ」写真、アップル提供=を2月2日に米国で発売すると発表した。価格は容量256ギガのモデルで、3499ドル(約500,000円)からとなる。16日から予約注文を受け付ける。

ビジョンドプロ、テア目の動き、声でアプリを操作し、コントローラーは不要となる。楽しんでいる時も、レンズ越しに周囲が認識できる。Appleのノットクラック最高経営責任者(CEO)は、「これまで作られてきたVR端末の中で、最も精神的な家庭を保た」とすかる声明を出した。

米国以外では、今年後半からの販売を予定している。

アップルはこれまで、iPhone (iPhone)やタブレット端末のiPad (iPad)といった画期的な製品を作り出してきた。米メディアによれば、アップルにとって、2014年発表の腕時計型端末、Apple Watch以外の主要な新製品になると言う。

ビジョンプロ、メタ(旧Facebook)のVR端末「目指クエストスリー」(499.99ドルからと言うに比べて・や高額となるが、アップルの参入で市場の拡大が期待される。

(読売新聞より転載)

人気ブログランキングへ←人気ブログランキングに参加しています。ポチっと1票を! 

Developments in AI

シンギュラリティ


240109 Developments in AI Part 1

Reasons for the dramatic evolution of AI The technological innovation of AI has been greatly advanced by the practical application of machine learning and the emergence of deep learning due to the improvement of the computing power of computers and the ability to utilize big data. What does each mean? Practical application  of machine learning Machine learning is the realization of the mechanism of "learning" in humans by computers.  It will automatically build algorithms that can identify and predict patterns and rules from input data and apply them to new data. Since the 2010s, it has become possible to handle vast amounts of information, and the practical application of machine learning has progressed. The advent of deep  learning In machine learning, there was a need for humans to define features and improve accuracy. A feature is an indicator of which parts to focus on in order to find patterns. Deep learning, which appeared there, is revolutionary in that it can automatically extract features from training data.  Advances in GPUs One of the key drivers for the evolution of AI is the development of graphics processing units (GPUs). It was not until the late 2000s ~ early 2010s that it became clear that its advanced parallel processing capabilities were suitable for AI learning tasks, especially deep learning. Prior to that, the computing power of GPUs was rarely used to train AI. Deep learning requires large amounts of data and computational power. Neural network training, in particular, can have millions or billions of parameters, and the calculations to update them all at the same time can be enormous. The CPU (Central Processing Unit) can perform these calculations, but the processing speed is limited. GPUs, on the other hand, have a large number of cores, which makes it possible to perform a large amount of calculations at the same time. As a result, deep learning computational tasks can be processed at high speed, and the training time of the AI can be greatly reduced. In addition, GPU maker NVIDIA offers CUDA, a platform dedicated to AI calculations. This allows developers to maximize the computing power of GPUs, further accelerating the evolution of AI. In this way, the development of GPUs has become an important foundation for the modern AI boom. What has happened with the evolution of AI What specific changes have occurred in our daily lives with the advent of AI and advances in technology? Here are some typical examples.  AI defeats humans in Go and Shogi In games that require strategies based on complex thoughts and patterns, the confrontation between strong human beings and AI is often the focus of attention. In 1997, IBM's Deep Blue AI defeated the then-world champion in chess. In shogi, in 2012, Compusoft defeated the top shogi players. In addition, Go, which was said to be difficult for AI to win because the board is wider than chess and shogi and has a large number of patterns, became a big topic in 2016 when top Go player Li Kudan was defeated by the computer program "AlphaGo".  The development of "Alpha Zero," an AI that allows players to learn on their own without looking at any past data such as game records, is also underway. Credit Card Fraud Monitoring The AI technology introduced by financial institutions to prevent credit card fraud is a system called "Regtech". In this system, AI that has learned from past fraud patterns monitors risk, and it is widely used for fraud countermeasures, such as online identity verification and anti-money laundering measures. AI recommendation function  Recommended products on e-commerce sites and SNSIt has become common for the above ads to be displayed based on an individual's purchase history and browsing history. It captures the interests and hobbies of each user and efficiently promotes products and content. On the other hand, it has been pointed out that AI recommendations lead to a loss of individual diversity. Autonomous driving It is expected that AI will improve convenience and significantly reduce traffic accidents by using AI to drive autonomously. It is also advantageous as a means of relieving traffic congestion and in rural areas where public transportation is scarce. As of 2022, "conditional autonomous driving cars (limited area)" have been realized in Japan. The autonomous driving system can be activated on highways, but if the system cannot continue autonomous driving, the driver must return to driving. In the future, it is expected that "autonomous driving cars (limited area)" that can drive on a predetermined route without driver involvement and "fully autonomous driving cars" that do not have restrictions on areas will be realized. Automatic Translation The technology that uses AI to translate words into another language is also remarkable. With the advent of deep learning, translations that are more natural and close to human translations are being realized. It is also used as a translator for overseas travel and when browsing websites written in foreign languages, and it has become familiar. Medical Imaging Diagnosis Advances in deep learning have also improved the technology for AI to recognize images. In the medical field, AI recognizes radiation images and supports the detection of abnormalities, which is useful for preventing oversights and improving operational efficiency.

 In 2021, there was a case where an AI system that supports diagnostic imaging of the new coronavirus was approved as a medical device. Advanced text generation from ChatGPT, Bing AI, and more One of the advances in AI in recent years has been the dramatic improvement in its ability to generate text. Typical examples are OpenAI's ChatGPT and Microsoft's Bing AI. These AIs can use natural language processing (NLP) technology to generate natural sentences that are easy for humans to understand. ChatGPT, in particular, has the ability to learn from large amounts of text data and generate natural conversations, and is widely used as a chatbot and writing aid tool for customer service. Bing AI, on the other hand, has the ability to explain the results of web searches in natural language. It also supports image generation, and  you can create a new image according to the user's instructions using "Bing Image Creator". Highly automatic generation of images and illustrations Automatic image and illustration generation technology is a technology that automatically generates images and illustrations by AI by inputting text and data. This technology is used in fields such as design and art. Specific examples of automatic image and illustration generation technologies include the following. ・ DALL・E When you enter text, it is an AI that generates an image that matches the content. For example, if you enter text such as "avocado-shaped chair" or "a bear is on Mars," an image corresponding to them will be generated. Stable Diffusion is an AI that generates high-quality images that match the content when text or images are input. For example, if you enter the text "cat", it will generate images of different types of cats. Also, if you input a person's face photo, you can generate a face photo of another person who looks like that person. The impact of the evolution of AI on society The evolution of AI has had a significant impact on society as a whole, from business to daily life, and in the manufacturing industry, for example, automation and optimization by AI is improving productivity. In addition, in customer service, AI chatbots are available 24 hours a day, 365 days a year, and customer satisfactionContributes to the improvement of. In the medical field, AI is being used as a diagnostic support system, leading to early detection and accurate diagnosis. In addition, the evolution of autonomous driving technology is expected to reduce traffic accidents and make effective use of time. AI is also being applied to the fields of education and learning, enabling individualized education such as the provision of teaching materials tailored to individual learning progress and comprehension. On the other hand, it is also true that the evolution of AI has raised concerns about employment. As automation with AI and robots advances, some jobs may disappear. In addition, the social impact of AI decisions and ethical issues are also among the issues. Introducing predictions for the next 10 years brought about by the evolution of AI AI 10 years from now, AI is expected to have even more advanced technologies and a wide range of applications than today. It is possible that AI will surpass humans and become more advanced problem-solving. For example, the day may come when AI will propose solutions to complex and large-scale problems such as climate change, economic recession, and disease epidemics.It will produce. AI is expected to be used in all aspects of daily life, such as household chores, childcare, and health management. It is predicted that the evolution of AI will drastically change our lives and further unlock the potential of human beings. On the other hand, however, the evolution of AI can also cause new problems. It cannot be ruled out that if human jobs are replaced by AI, employment instability and economic disparity will widen further. In addition, if AI processes large amounts of personal information, the risk of privacy violations and information leaks may increase. Furthermore, as AI judgment becomes deeply involved in human society, it will be important to take measures against AI ethics and errors caused by AI judgment. As AI evolves, measures and regulations to address these issues will also be necessary. The future of AI is full of great potential and challenges. We need to fully understand the impact of AI and respond appropriately. The next 10 years will be an important turning point for the evolution of AI and building a new relationship with society. Advantages and disadvantages of the evolution of AI Let's summarize the advantages and disadvantages of the evolution of AI. Advantages 1. Elimination of labor shortageThe problem of labor shortage may be solved by AI taking on tasks that are difficult for humans to perform and simple labor. In particular, it is expected to be used in fields where there is a shortage of manpower, such as a serious shortage of nursing care personnel in an aging society. 2. Productivity improvementAI can process large amounts of data at high speed, which greatly contributes to improving productivity in the manufacturing and service industries. 3. Reduction of mistakes and accidents and improvement of safetySince AI judgment is always constant and does not get tired like humans, it can be expected to reduce the number of mistakes and accidents that humans can cause. For example, if autonomous driving technology evolves further, it will lead to a decrease in traffic accidents. 4. Cost reductionAI can operate 24 hours a day and contributes to reducing human labor costs. In addition, automation and optimization by AI will reduce costs through efficient business operations. 5. Improvement of customer satisfactionAI recommendation functions, chatbots, etc., improve the quality of service to customers, and improve customer satisfaction. Enhancing. Disadvantages 1.Possibility of human jobs being taken awayAs efficiency and automation by AI advances, there is a possibility that some human jobs will be replaced by AI. There are concerns that this will lead to instability in employment, especially for unskilled labor. Liability in the event of a malfunction in the judgment of the 2.AI In the event of an accident or problem caused by the judgment of the AI, the question is who should be held responsible. This is one of the major challenges from the perspective of law and ethics. 3. Privacy IssuesWhen AI processes a large amount of personal information, the risk of privacy invasion due to information leakage or inappropriate use increases. Data privacy and security will become increasingly important as AI becomes more prevalent. 4. Dangers of military use: The military use of AI technology has the potential to create a new military balance and style of warfare. There will be an urgent need to create international rules for the development and use of AI weapons. 5. Security IssuesAI systems themselves can be the target of cyberattacks, and security measures are an important issue. In particular, the security of systems that affect human life, such as self-driving cars and medical AI, has become a top priority. In light of these advantages and disadvantages, there is an increasing need for specific measures and regulations in each field to deal with the problems that arise with the evolution of AI. What is the Singularity? AI technology will surpass humans and become smarter than humans, which is called the "singularity" (technological singularity) , Singularity). The singularity will make it possible for AI to do things that only humans could do until now. For example, it has been pointed out that human jobs may be replaced by AI, or that AI may harm humans. Frequently Asked Questions about the Evolution of AI Here are some frequently asked questions about AI and its evolution. What happens when AI evolves? Initially, AI could only solve simple problems under set rules, but with the development of machine learning that inputs a large amount of knowledge and deep learning technology that can extract indicators for pattern classification on its own, the technology has advanced dramatically. It has been proposed that the "singularity (technological singularity)" in which AI will surpass humans will come in 2045 and may have a major impact on our lives. What jobs will disappear as AI evolves? As AI evolves and automation and efficiency increases, it is likely that the following occupations and operations will be affected. ・Manufacturing, transportation, retail, customer service, accounting and financial services However, while AI will take over jobs, new jobs and jobs related to AI may also be created. In addition, it is thought that creative work that AI is not good at and jobs that emphasize communication with humans will continue to be handled by humans. What is the future of AI robots? AI-equipped robots are being put to practical use, and the market is expanding. AI can learn human facial expressions and communication through technology, so it can be used in a variety of situations. Service robots such as "aibo" and "Pepper" are expected to greatly exceed the market size of industrial robots in the future. Will AI surpass humans? When the singularity arrives, in which AI surpasses humans, there is a possibility that phenomena that were previously thought to be only events in science fiction novels and movies will become a reality. It is important for AI to utilize technology while taking into account risky actions and ethical aspects. What can AI do in the future? AI continues to evolve day by day, and its possibilities are vast. Among them, the following are expected to be possible in the future. ・Evolution of general dialogue AI, creative work, medical diagnosis and treatment, complete independence of autonomous driving, prediction and decision-making support These are just a few examples, and the possibilities of AI will be further expanded by future technological advances and research. A future that coexists with AI and builds The technology surrounding AI has advanced remarkably in just over 70 years.  AI, which can "learn" using big data and make decisions based on processes close to human thinking if the area is limited, has the potential to be able to do things that were previously thought to be "only human." It has also been pointed out that AI technology deprives humans of the ability to think. On the other hand, if used well, it can help us learn and act more productively, leading to economic growth and the development of new technologies. In preparation for the singularity, we would like to focus not only on AI technology that is growing rapidly, but also on its literacy and environmental improvement.

人気ブログランキングへ←人気ブログランキングに参加しています。ポチっと1票を!  

240108AIシンギュラリティ

240108AIシンギュラリティ
AIが飛躍的に進化した理由 AIの技術革新を大きく進めたのは、コンピューターの計算能力が向上し、ビッグデータの活用が可能になったことによる機械学習の実用化と深層学習の登場だ。それぞれどのような意味を持つのか。 機械学習の実用化 機械学習とは、人間における「学習」の仕組みをコンピューターで実現するものだ。入力されたデータからパターンやルールを見つけ出し、新たなデータに当てはめて識別や予測ができるアルゴリズムを自動的に構築するようになる。
2010年代以降、膨大な情報を扱うことができるようになり、機械学習の実用化が進んだ。 深層学習の登場 機械学習では、人間が特徴量を定義し精度を上げる必要性があった。特徴量とは、パターンを見つけ出すためにどの部分に着目するかという指標だ。そこで登場した深層学習は、学習データから自動で特徴量を抽出できる点が画期的である。
GPUの発達 AIの進化に対する重要な推進力の一つとして、GPUグラフィックス・プロセッシング・ユニット)の発展が挙げられる。その高度な並列処理能力がAIの学習タスク、特に深層学習に適していることが明らかになったのは、2000年代後半~2010年代前半にかけてのことだ。それ以前は、GPUの計算能力をAIの学習に活用することはほとんどなかった
深層学習は大量のデータと計算力を必要とする。特にニューラルネットワークの訓練は、数百万から数十億のパラメータを持つことがあり、それら全てを同時に更新するための計算は膨大なものになる。CPU(中央処理装置)でもこれらの計算は可能だが、その処理速度は限られている。
これに対してGPUは、多数のコアを持つことで、大量の計算を同時並行で行うことが可能だ。このため、深層学習の計算タスクを高速に処理することができ、AIの訓練時間を大幅に短縮することが可能となった。 また、GPUメーカーであるNVIDIAは、AIの計算に特化したプラットフォーム「CUDA」を提供している。
これにより、開発者はGPUの計算能力を最大限に引き出すことが可能となり、AIの進化をさらに加速している。このように、GPUの発達は現代のAIブームを支える重要な基盤となっている。 AIの進化で何が起きたのか AIが登場し、技術が進歩したことで、私たちの日常には具体的にどのような変化があったのか。代表的な事例を紹介する。 囲碁や将棋でAIが人間に勝利 複雑な思考やパターンによる戦略を要するゲームでは、人間の強者とAIとの対決がたびたび注目される。
1997年には、米IBMが開発したAI「ディープ・ブルーがチェスで当時の世界チャンピオンに勝った。 将棋では、2012年にコンピュソフトがトップ棋士に勝利する。さらに、チェスや将棋に比べて盤面が広くパターン数が多いためAIが勝利するのは難しいと言われていた囲碁でも、2016年、コンピュータープログラム「アルファ碁」にトップ棋士の李九段が敗れて大きな話題となった。棋譜など過去のデータを一切見ずに自ら学ぶことができるAI「アルファゼロ」の開発も進んでいる。 クレジットカードの不正監視 クレジットカードの不正対策に金融機関で導入されているAI技術が「レグテック」というシステムだ。このシステムでは、過去の不正パターンを機械学習したAIがリスクを監視しており、オンラインでの本人確認や、マネーロンダリング対策など、不正対策に幅広く活用されている。
AIレコメンド機能 ECサイトのおすすめ商品や、SNS上の広告などは個人の購入履歴や閲覧履歴に基づいて表示されることが一般的になった。ユーザーそれぞれの関心や趣味を捉え、効率的に商品やコンテンツが宣伝される。一方で、AIのレコメンドによって個人の多様性が失われるとの指摘もある。 自動運転 自動車をAIが自動で運転することで利便性を向上し、交通事故を大幅に減らせるのではないかと期待されている。渋滞の緩和策や公共交通機関が少ない地方での移動手段としてもメリットがある。
2022年現在、日本では「条件付自動運転車(限定領域)」が実現している。高速道路などにおいて自動運転システムを作動できるが、システムが自動運転を継続できなくなればドライバーは運転に戻らなければならない。 今後は、ドライバーの関与がなくても決められたルートを走行できる「自動運転車(限定領域)」や、領域の制限がなくなる「完全自動運転車」の実現が想定される。 自動翻訳 AIを用いて言葉を別の言語に翻訳する技術も顕著だ。
深層学習の登場によって、より自然で人間が訳したような言葉に近い翻訳が実現されつつある海外旅行用の翻訳機や外国語で書かれたウェブサイトを閲覧する際などにも使われ、身近になっている。 医療画像診断 深層学習の進歩で、AIが画像を認識する技術も向上した。医療現場では放射線画像などをAIが認識し、異常の検知などを支援しており、見落としの防止や業務効率化に役立っているという。 2021年には、新型コロナウイルスの画像診断を支援するAIシステムが医療機器として承認された事例もある。
ChatGPT、Bing AIなどの高度なテキスト生成 近年におけるAIの進化の一つとしては、テキスト生成能力の飛躍的な向上が挙げられる。その代表例がOpenAIの「ChatGPT」Microsoftの「Bing AI」だ。これらのAIでは、自然言語処理NLP技術を用いて人間が理解しやすい自然な文章を生成できる。 特に「ChatGPT」は、大量のテキストデータから学習して自然な会話を生成する能力があり、カスタマーサービスのチャットボットや文章作成補助ツールとして広く活用されている傾向だ。一方「Bing AI」は、Web検索の結果を自然な言葉で説明する能力を持つ。 画像生成にも対応しており、「Bing Image Creatorを使いユーザーの指示に従って新しい画像を作成できる。
画像・イラストも高度に自動生成 画像やイラストの自動生成技術とは、テキストやデータなどを入力することでAIが自動的に画像やイラストを生成してくれる技術だ。この技術は、デザインやアートなどの分野で活用されている。画像やイラストの自動生成技術の具体例としては、以下のようなものがある。 ・DALL・Eテキストを入力すると、その内容に合った画像を生成するAIだ。例えば「アボカドの形をした椅子」「熊が火星にいる」といったテキストを入力すると、それらに対応した画像を生成する。 ・Stable Diffusionテキストや画像を入力すると、その内容に合った高品質な画像を生成するAIだ。例えば「猫」というテキストを入力すると、さまざまな種類の猫の画像を生成する。また人物の顔写真を入力すると、その人物に似た別人物の顔写真の生成が可能だ。
AIの進化が社会にもたらす影響 AIの進化は、ビジネスから日常生活まで社会全体に大きな影響を与えており、例えば製造業ではAIによる自動化と最適化が生産性を向上させている。ほかにもカスタマーサービスでは、AIチャットボットが24時間365日対応可能となり、顧客満足度の向上に寄与。医療分野では、AIが診断支援システムとして活用され、早期発見や正確な診断につながっている。 さらに自動運転技術の進化により、交通事故の減少や時間の有効活用の期待度も高い。またAIが教育や学習の分野にも応用されており、個々の学習進度や理解度に合わせた教材提供など個別対応の教育が可能となっている。一方でAIの進化は、雇用に対する懸念をもたらしていることも事実だ。
AIやロボットによる自動化が進むことで、一部の職種がなくなる可能性がある。またAIの判断による社会的な影響や倫理的な問題も課題の一つだ。 AIの進化がもたらす10年後の予測を紹介 10年後のAIは、今よりもさらに高度な技術と広範な応用が期待されている。AIの能力が人間を超え、より高度な問題解決能力を持つようになる可能性があるのだ。例えば気候変動や経済不況、病気の流行など複雑で大規模な問題に対する解決策をAIが提案する日が来るかもしれない またAIは、人間の生活をより便利で快適にするための新たなテクノロジーを生み出すだろう。
家庭内の家事や育児、健康管理など日常生活のあらゆる面においてAIの活用が期待される。AIの進化により、私たちの生活は大きく変わり人間の可能性をさらに引き出すことになると予測されているのだ。 しかしその一方でAIの進化は新たな問題を引き起こす可能性もある。
人間の仕事がAIに置き換わると雇用の不安定化や経済格差の拡大がさらに進む可能性も否定できない。またAIが個人情報を大量に処理することになるとプライバシー侵害や情報漏えいのリスクも増えるかもしれない。 さらにAIの判断が人間社会に深く関与するようになると、AIの倫理やAIの判断による誤りに対する対策が重要となる。AIが進化する一方で、これらの課題へ向けた対策や規制も必要となるだろう。AIの未来は、大きな可能性と課題を併せ持つ。 私たちはAIの影響を十分に理解した上で適切に対応することが求められる。今後の10年がAIの進化と社会との新たな関係を築く重要な分岐点となるだろう。
AIの進化によるメリット・デメリット ここで、AIの進化によるメリット・デメリットを整理しておこう。
メリット 1.労働力不足の解消人間が行うのが困難な作業や単純労働をAIが担うことで、労働力不足の問題が解消される可能性がある。特に高齢化社会における深刻な介護人材の不足など、人手が足りない分野での活用が期待されている。
2.生産性の向上AIは、大量のデータを高速に処理できるため、製造業やサービス業などの生産性向上に大いに寄与する。
3.ミスや事故の減少と安全性の向上AIの判断は、常に一定で人間のように疲れることがないため、人間が起こす可能性のあるミスや事故を減らすことが期待できる。例えば自動運転技術がより一層進化していけば、交通事故の減少につながるだろう。
4.コストの削減AIは、24時間稼働でき人間の労働コスト削減に寄与する。またAIによる自動化や最適化は、効率的な業務運営によるコスト削減をもたらす。
5.顧客満足度の向上AIのレコメンド機能やチャットボットなどは、顧客に対するサービスの質を向上させ、顧客満足度を高める。
デメリット 1.人間の仕事が奪われる可能性AIによる効率化や自動化が進むと一部の人間の仕事がAIに置き換わる可性がある。これは、特に単純労働を中心に雇用の不安定化を引き起こす懸念がある。
2.AIの判断に不具合が起こった場合の責任AIの判断による事故や問題が起きた場合、その責任を誰が負うべきかが問題となる。これは、法律や倫理の観点からも大きな課題の一つだ。
3.プライバシーの問題AIが個人情報を大量に処理することになると情報漏えいや不適切な利用によるプライバシー侵害のリスクが増える。データプライバシーとセキュリティはAIの普及に伴い、ますます重要な課題となるだろう。
4.軍事利用の危険性AIの技術が軍事利用されることで、新たな軍事バランスや戦争スタイルが生まれる可能性がある。AI兵器の開発や使用に関する国際的なルール作りが急務となるだろう。
5.セキュリティの問題AIシステム自体がサイバー攻撃の対象となることもあり、そのセキュリティ対策は重要な課題となる。特に、自動運転車や医療AIなど、人命に関わるシステムのセキュリティは最重要課題となっている。 これらのメリットとデメリットを踏まえ、AIの進化とともに生じる問題にどう対処するか、それぞれの分野での具体的な対策と規制の必要性がますます高まっている。
シンギュラリティとは? AI技術が人間を超え、自ら人間より賢い知能を持つようになることを「シンギュラリティ(技術的特異点、Singularity)」と呼ぶ。 シンギュラリティによって、これまで人間にしかできなかったことがAIにも可能になる。例えば、人間の仕事がAIに置き換えられたり、AIが人間に危害を加えたりする可能性も指摘されている。
AIの進化についてよくある質問 AIとその進化に関して、よくある疑問についてまとめた。 AIが進化するとどうなる? 当初は、決められたルールの下で簡単な問題を解くことしかできなかったAIだが、大量の知識をインプットする機械学習や、自らパターン分けのための指標を抽出できる深層学習の技術が開発され、その技術は飛躍的に進歩した。
AIが人間を超える「シンギュラリティ(技術的特異点)」が2045年に訪れ、私たちの生活に大きな影響を及ぼす可能性があると提唱されている。 AIが進化するとなくなる仕事は? AIが進化し、自動化や効率化が進むと、特に以下のような職種や業務が影響を受ける可能性が高いと考えられている。 ・製造業・運輸業・小売業・顧客サービス・会計と金融サービス ただし、AIが仕事を奪う一方で、AIに関連する新たな職種や仕事が生まれる可能性もある。
また、AIが苦手とするクリエイティブな仕事や人間とのコミュニケーションを重視する仕事は、今後も人間によって担われると考えられる。 AIロボットの将来性は? AIを搭載したロボットは実用化が進み、市場も拡大している。AIは技術によって人間の表情やコミュニケーションを学ぶことができるため、さまざまな場面で活用される。「aibo」や「Pepper」などのサービスロボットは今後、産業用ロボットの市場規模を大きく上回ると予測されている。
AIは人間を超えるのか? AIが人間を超えるシンギュラリティが訪れると、これまではSF小説や映画の中だけの出来事だと考えられてきた現象が現実になる可能性もある。AIが、リスクとなる行為や倫理面に配慮した上で技術を活用していくことが重要だ。 AIが今後できるようになることは? AIの進化は日々続いており、その可能性は広大だ。中でも、今後できるようになることとしては以下が予想されている。
・一般的な対話AIの進化・クリエイティブな作業・医療診断と治療・自動運転の完全自立・予測と意思決定の支援 これらは一部の例であり、AIの可能性はこれからの技術進歩や研究によってさらに広がるだろう。 AIと共存し築く未来 AIをめぐる技術はわずか70年ほどの間にめざましく進歩した。ビッグデータを使って「学ぶ」ことができ、領域を限定すれば人間の思考に近いプロセスで判断できるAIは、これまで「人間にしかできない」と思われていたことができるようになる可能性を持つ。 AI技術は人間の思考能力を奪うとの指摘もある。一方で、うまく活用すれば私たちがより生産的に学び、行動する助けにもなり得るし、経済成長や新たな技術開発にもつながる。シンギュラリティに備え、急成長を遂げるAI技術だけでなく、そのリテラシーや環境整備にも着目したい。 
(図、文章ともネットより転載)

人気ブログランキングへ←人気ブログランキングに参加しています。ポチっと1票を!

 

240106 Python 組み込み関数全71件 完全解説(Qiitaより転載)

class関数


240106 Python 組み込み関数全71件 完全解説

使いこなせていますか?Python 組み込み関数全71件 完全解説[2023 最新版]

投稿日 2023年12月05日

この記事はNuco Advent Calendar 2023の5日目の記事です。

はじめに

Pythonは、世界中で広く使われているプログラミング言語の一つです。Pythonの特徴の一つは、豊富な組み込み関数を持っていることです。

Pythonの組み込み関数は、2023年12月現在、全71件あります。しかし、それらを完璧に使いこなせている人はどれくらいいるでしょうか?

この記事では、Pythonの組み込み関数全71件を、実際のコード例も踏まえて完全解説します。この記事を読めば、Pythonの組み込み関数について、一から十まで理解できるでしょう。

それでは、早速見ていきましょう。

弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています!興味をお持ちいただける方は、こちらまで。

組み込み関数の一覧

(1)abs()

引数の絶対値を返します。

num = -5

assert abs(num) == 5

  • 注意点
    引数が数値以外のオブジェクトの場合、__abs__()メソッドが定義されている必要があります。

class Vector:

    def __init__(self, x, y):

        self.x = x

        self.y = y

 

    def __abs__(self):

        return (self.x ** 2 + self.y ** 2) ** 0.5

 

v = Vector(3, 4)

assert abs(v) == 5

この関数を知らないと…
絶対値を求める際に、不要な条件分岐の実装や、不要なモジュールのインポートが発生します。

import math

 

num = -5

if num < 0:

    num = -num

assert num == 5

 

num = -5

num = math.fabs(num)

assert num == 5

(2)aiter()

引数に指定した非同期イテラブルオブジェクトを非同期イテレータに変換します。非同期イテラブルオブジェクトとは、__aiter__()メソッドを持つオブジェクトで、非同期イテレータを返すものです。非同期イテレータとは、__anext__()メソッドを持つオブジェクトで、非同期ジェネレータを返すものです。

import asyncio

 

async def async_gen():

    for i in range(3):

        yield i

        await asyncio.sleep(1)

 

async def main():

    async for i in aiter(async_gen()):

        print(i)

 

asyncio.run(main()) # 0, 1, 2を1秒ごとに出力

  • 注意点
    aiter()は非同期イテラブルオブジェクトに対してのみ有効です。通常のイテラブルオブジェクトに対してはTypeErrorを発生させます。

aiter([1, 2, 3]) # TypeError: 'list' object is not an async iterable

この関数を知らないと…
非同期イテラブルオブジェクトをfor文で回す際に、async forを使わなければなりません。しかし、async forはawait式の中で使えません。その場合、aiter関数を使って非同期イテレータに変換し、anext関数で要素を取り出すことができます。

import asyncio

 

async def async_gen():

    for i in range(3):

        yield i

        await asyncio.sleep(1)

 

async def main():

    async_iter = aiter(async_gen())

    while True:

        try:

            i = await anext(async_iter)

            print(i)

        except StopAsyncIteration:

            break

 

asyncio.run(main())

(3)all()

引数(イテラブルオブジェクト)の全ての要素がTrueならば、Trueを返します。

arr = [True, True]

assert all(arr) is True

 

arr = [True, False]

assert all(arr) is False

  • 注意点
    引数の要素が空の場合にはTrueを返します。

arr =

assert all(arr) is True

この関数を知らないと…
複数条件の比較の際にandを連発して冗長なコードを書いてしまいます。

sample_1 = True

sample_2 = True

sample_3 = False

sample_4 = True

sample_5 = False

assert (sample_1 is True and sample_2 is True and sample_3 is True and sample_4 is True and sample_5 is True) is True

all関数を使うと以下のように書くことができます。

sample_1 = True

sample_2 = True

sample_3 = False

sample_4 = True

sample_5 = False

arr = [sample_1, sample_2, sample_3, sample_4, sample_5]

assert all(arr) is True

(4)anext()

引数に指定した非同期イテレータから次の要素を取得します。戻り値は非同期ジェネレータです。引数にデフォルト値を指定した場合、非同期イテレータが終了したときにその値を返します。デフォルト値を指定しない場合、非同期イテレータが終了したときにStopAsyncIterationExceptionを発生させます。

import asyncio

 

async def async_gen():

    for i in range(3):

        yield i

        await asyncio.sleep(1)

 

async def main():

    it = aiter(async_gen())

    print(await anext(it)) # 0

    print(await anext(it)) # 1

    print(await anext(it)) # 2

    print(await anext(it, 'end')) # end

 

asyncio.run(main())

  • 注意点
    anext()は非同期イテレータに対してのみ有効です。通常のイテレータに対してはTypeErrorを発生させます。

anext(iter([1, 2, 3])) # TypeError: 'list_iterator' object is not an async iterator

こういうときに便利
非同期イテレータから要素を取り出す際に、特定の条件を満たす要素だけを選択したいときに便利です。例えば、以下のコードでは、非同期イテレータから奇数だけを取り出しています。

import asyncio

 

async def async_gen():

    for i in range(10):

        yield i

        await asyncio.sleep(1)

 

async def main():

    async_iter = aiter(async_gen())

    while True:

        try:

            i = await anext(async_iter)

            if i % 2 == 1:

                print(i)

        except StopAsyncIteration:

            break

 

asyncio.run(main())

 

(5)any()

引数(イテラブルオブジェクト)のいずれかの要素がTrueならば、Trueを返します。

arr = [True, False]

assert any(arr) is True

 

arr = [False, False]

assert any(arr) is False

  • 注意点
    引数の要素が空の場合にはFalseを返します。

arr =

assert any(arr) is False

この関数を知らないと…
複数条件の比較の際にorを連発して冗長なコードを書いてしまいます。

sample_1 = True

sample_2 = False

sample_3 = False

sample_4 = False

sample_5 = False

assert (sample_1 is True or sample_2 is True or sample_3 is True or sample_4 is True or sample_5 is True) is True

any関数を使うと以下のように書くことができます。

sample_1 = True

sample_2 = False

sample_3 = False

sample_4 = False

sample_5 = False

arr = [sample_1, sample_2, sample_3, sample_4, sample_5]

assert any(arr) is True

(6)ascii()

引数(オブジェクト)のASCII表現を文字列として返します。

s = 'こんにちは'

assert ascii(s) == "'\\u3053\\u3093\\u306b\\u3061\\u306f'"

  • 注意点
    引数のオブジェクトがASCII文字のみで構成されている場合には、そのままの文字列を返します。

s = 'Hello'

assert ascii(s) == "'Hello'"

こういうときに便利
非ASCII文字を含むオブジェクトをファイルに書き込んだり、他のプログラムに渡したりするときに、ascii関数を使って文字列に変換すると便利です。例えば、以下のように書くことができます。

s = 'こんにちは'

with open('test.txt', 'w') as f:

    f.write(ascii(s))

# test.txtには'\u3053\u3093\u306b\u3061\u306f'と書かれる

import json

s = 'こんにちは'

data = {'message': ascii(s)}

json_data = json.dumps(data)

# json_dataは'{"message": "\\u3053\\u3093\\u306b\\u3061\\u306f"}'となる

(7)bin()

引数の整数を2進数の文字列に変換して返します。

num = 10

assert bin(num) == '0b1010'

  • 注意点
    整数以外のオブジェクトに対しては、__index__()メソッドが定義されている必要があります。

class Bit:

    def __init__(self, value):

        self.value = value

 

    def __index__(self):

        return self.value

 

b = Bit(10)

assert bin(b) == '0b1010'

この関数を知らないと…
2進数の文字列に変換する際に、自分でビット演算や文字列操作を行う必要があります。

num = 10

result = ''

while num > 0:

    result = str(num % 2) + result

    num //= 2

result = '0b' + result

assert result == '0b1010'

bin関数を使うと以下のように書くことができます。

num = 10

result = bin(num)

assert result == '0b1010'

(8)bool()

引数を真偽値に変換して返します。引数が真とみなされる場合はTrue、偽とみなされる場合はFalseを返します。

assert bool(1) is True

assert bool(0) is False

assert bool('Hello') is True

assert bool('') is False

  • 注意点
    引数がない場合にはFalseを返します。

assert bool() is False

こういうときに便利
条件分岐やループの制御にbool関数を使って、引数の真偽値を判定すると便利です。

x = input('Enter something: ')

if bool(x):

    print('You entered:', x)

else:

    print('You entered nothing')

arr = [1, 2, 3, 0, 4, 5]

for x in arr:

    if bool(x):

        print(x, 'is True')

    else:

        print(x, 'is False')

(9)breakpoint()

プログラムの実行を一時停止してデバッガに制御を渡す関数です。Python 3.7以降で導入されました。

def factorial(n, sum=0):

    if n == 0:

        return sum

    # デバッグポイントを設定

    breakpoint()

    sum += n

    print(sum)

    return factorial(n-1, sum)

 

if __name__ == '__main__':

    factorial(5)

  • 注意点
    breakpoint関数は、環境変数PYTHONBREAKPOINTに設定されたデバッガを呼び出します。デフォルトではpdbモジュールが使用されますが、他のデバッガを指定することもできます。

# ipdbモジュールを使用する場合

import os

os.environ['PYTHONBREAKPOINT'] = 'ipdb.set_trace'

この関数を知らないと…
プログラムの実行中に変数の値や実行のフローを確認するために、print関数やpdbモジュールを直接コードに挿入してしまいます。これはコードの可読性や保守性を低下させる可能性があります。

def factorial(n, sum=0):

    if n == 0:

        return sum

    # print関数で変数の値を確認

    print('n:', n, 'sum:', sum)

    # pdbモジュールでデバッグポイントを設定

    import pdb; pdb.set_trace()

    sum += n

    print(sum)

    return factorial(n-1, sum)

 

if __name__ == '__main__':

    factorial(5)

breakpoint関数を使うと以下のように書くことができます。

def factorial(n, sum=0):

    if n == 0:

        return sum

    # breakpoint関数でデバッグポイントを設定

    breakpoint()

    sum += n

    print(sum)

    return factorial(n-1, sum)

 

if __name__ == '__main__':

    factorial(5)

(10)bytearray()

引数によって指定されたバイト列を表す可変なシーケンスオブジェクトを返します。

# 引数が整数の場合、その長さのゼロで埋められたバイト列を作ります。

ba = bytearray(5)

print(ba) # bytearray(b'\x00\x00\x00\x00\x00')

 

# 引数が文字列の場合、エンコーディングを指定してバイト列に変換します。

ba = bytearray("Hello", "utf-8")

print(ba) # bytearray(b'Hello')

 

# 引数がイテラブルオブジェクトの場合、その要素をバイト値として使用します。

ba = bytearray([65, 66, 67])

print(ba) # bytearray(b'ABC')

  • 注意点
    bytearrayオブジェクトは可変なので、要素の追加や削除、スライスの代入などができます。しかし、要素は0から255の範囲の整数でなければなりません。

ba = bytearray(b"Hello")

ba[0] = 74 # b'H'をb'J'に変更

print(ba) # bytearray(b'Jello')

 

ba.append(33) # b'!'を追加

print(ba) # bytearray(b'Jello!')

 

ba[1:4] = b"ohn" # b'ell'をb'ohn'に置き換え

print(ba) # bytearray(b'John!')

 

ba[0] = 256 # 0から255の範囲外の値はエラーになる

# ValueError: byte must be in range(0, 256)

この関数を知らないと…
バイト列を扱うときに、bytesオブジェクトを使ってしまいます。bytesオブジェクトは不変なので、要素の変更や追加ができません。そのため、新しいバイト列を作るためには、毎回bytesオブジェクトを作り直す必要があります。これは非効率的で、メモリの無駄になります。

b = b"Hello"

b[0] = 74 # bytesオブジェクトは不変なのでエラーになる

# TypeError: 'bytes' object does not support item assignment

 

b += b"!" # 新しいbytesオブジェクトを作って連結する

print(b) # b'Hello!'

bytearray関数を使うと、バイト列を簡単に変更できます。

ba = bytearray(b"Hello")

ba[0] = 74 # bytearrayオブジェクトは可変なので変更できる

print(ba) # bytearray(b'Jello')

 

ba += b"!" # 既存のbytearrayオブジェクトに追加できる

print(ba) # bytearray(b'Jello!')

(11)bytes()

引数によって指定されたバイト列を表す不変なシーケンスオブジェクトを返します。

# 引数が整数の場合、その長さのゼロで埋められたバイト列を作ります。

b = bytes(5)

print(b) # b'\x00\x00\x00\x00\x00'

 

# 引数が文字列の場合、エンコーディングを指定してバイト列に変換します。

b = bytes("Hello", "utf-8")

print(b) # b'Hello'

 

# 引数がイテラブルオブジェクトの場合、その要素をバイト値として使用します。

b = bytes([65, 66, 67])

print(b) # b'ABC'

  • 注意点
    bytesオブジェクトは不変なので、要素の変更や追加、削除などができません。そのため、新しいバイト列を作るためには、別のbytesオブジェクトと連結したり、bytearrayオブジェクトに変換したりする必要があります。

b = b"Hello"

b[0] = 74 # bytesオブジェクトは不変なのでエラーになる

# TypeError: 'bytes' object does not support item assignment

 

b += b"!" # 新しいbytesオブジェクトを作って連結する

print(b) # b'Hello!'

 

ba = bytearray(b) # bytearrayオブジェクトに変換する

ba[0] = 74 # bytearrayオブジェクトは可変なので変更できる

print(ba) # bytearray(b'Jello!')

この関数を知らないと…
バイト列を扱うときに、文字列を使ってしまいます。文字列はエンコーディングに依存するので、バイナリデータとして扱うことができません。そのため、ファイルの読み書きやネットワークの通信などで問題が発生する可能性があります。

s = "Hello"

f = open("test.txt", "w") # テキストモードでファイルを開く

f.write(s) # 文字列を書き込む

f.close()

 

f = open("test.txt", "rb") # バイナリモードでファイルを開く

b = f.read() # バイト列を読み込む

f.close()

print(b) # b'Hello'

 

s = "こんにちは"

f = open("test.txt", "w") # テキストモードでファイルを開く

f.write(s) # 文字列を書き込む

f.close()

 

f = open("test.txt", "rb") # バイナリモードでファイルを開く

b = f.read() # バイト列を読み込む

f.close()

print(b) # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'

bytes関数を使うと、文字列をバイト列に変換できます。

s = "Hello"

b = bytes(s, "utf-8") # 文字列をバイト列に変換

f = open("test.txt", "wb") # バイナリモードでファイルを開く

f.write(b) # バイト列を書き込む

f.close()

 

f = open("test.txt", "rb") # バイナリモードでファイルを開く

b = f.read() # バイト列を読み込む

f.close()

print(b) # b'Hello'

 

s = "こんにちは"

b = bytes(s, "utf-8") # 文字列をバイト列に変換

f = open("test.txt", "wb") # バイナリモードでファイルを開く

f.write(b) # バイト列を書き込む

f.close()

 

f = open("test.txt", "rb") # バイナリモードでファイルを開く

b = f.read() # バイト列を読み込む

f.close()

print(b) # b'\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xe3\x81\xaf'

(12)callable()

引数が呼び出し可能なオブジェクト(関数やメソッドなど)であればTrueを、そうでなければFalseを返します。

def add(x, y):

    return x + y

 

print(callable(add)) # True

print(callable(3)) # False

print(callable(print)) # True

print(callable("Hello")) # False

  • 注意点
    callable関数は、オブジェクトが呼び出し可能であるかどうかを判定するだけで、実際に呼び出すことはできません。呼び出し可能なオブジェクトを実際に呼び出すには、カッコと引数を付けて実行します。

def add(x, y):

    return x + y

 

callable(add) # True

add(3, 4) # 7

 

callable(3) # False

3(5) # エラーになる

# TypeError: 'int' object is not callable

この関数を知らないと…
オブジェクトが呼び出し可能かどうかを確認するときに、try-except文を使ってエラーを捕捉してしまいます。これは冗長で、パフォーマンスに影響する可能性があります。

def add(x, y):

    return x + y

 

def is_callable(obj):

    try:

        obj()

        return True

    except TypeError:

        return False

 

print(is_callable(add)) # True

print(is_callable(3)) # False

callable関数を使うと、簡潔に書くことができます。

def add(x, y):

    return x + y

 

print(callable(add)) # True

print(callable(3)) # False

(13)chr()

引数に指定されたUnicodeコードポイントに対応する文字を返します。

print(chr(65)) # A

print(chr(97)) # a

print(chr(12354)) # あ

print(chr(128512)) # 😀

  • 注意点
    引数は0から1114111の範囲の整数でなければなりません。それ以外の値はエラーになります。

print(chr(-1)) # エラーになる

# ValueError: chr() arg not in range(0x110000)

 

print(chr(1114112)) # エラーになる

# ValueError: chr() arg not in range(0x110000)

この関数を知らないと…
Unicodeコードポイントから文字を得るために、エンコーディングやバイト列を使って変換してしまいます。これは複雑で、エラーが発生しやすいです。

# UTF-8エンコーディングを使ってコードポイントから文字を得る

def codepoint_to_char(codepoint):

    b = codepoint.to_bytes(4, "big") # コードポイントをバイト列に変換

    b = b.lstrip(b"\x00") # 先頭のゼロを除去

    return b.decode("utf-8") # バイト列を文字列に変換

 

print(codepoint_to_char(65)) # A

print(codepoint_to_char(97)) # a

print(codepoint_to_char(12354)) # あ

print(codepoint_to_char(128512)) # 😀

chr関数を使うと、簡単に文字を得ることができます。

print(chr(65)) # A

print(chr(97)) # a

print(chr(12354)) # あ

print(chr(128512)) # 😀

(14)classmethod()

引数に指定された関数をクラスメソッドに変換して返します。クラスメソッドとは、クラスオブジェクト自身を第一引数として受け取るメソッドのことです。クラスメソッドは、インスタンス化されたオブジェクトではなく、クラスオブジェクトから直接呼び出すことができます。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

    @classmethod # クラスメソッドにするためのデコレータ

    def from_birth_year(cls, name, birth_year): # 第一引数にクラスオブジェクトを受け取る

        age = 2023 - birth_year # 年齢を計算する

        return cls(name, age) # クラスオブジェクトを使ってインスタンスを作る

 

p1 = Person("Alice", 25) # 通常の方法でインスタンスを作る

p2 = Person.from_birth_year("Bob", 1998) # クラスメソッドを使ってインスタンスを作る

print(p1.name, p1.age) # Alice 25

print(p2.name, p2.age) # Bob 25

こういうときに便利
クラスメソッドは、クラスのインスタンスを作成するための別のコンストラクタとして使うことができます。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

    @classmethod

    def from_birth_year(cls, name, birth_year):

        age = 2023 - birth_year

        return cls(name, age)

 

p1 = Person("Alice", 25)

p2 = Person.from_birth_year("Bob", 1998)

print(p1.name, p1.age) # Alice 25

print(p2.name, p2.age) # Bob 25

このように、クラスメソッドを使うと、引数の形式に応じてインスタンスを作ることができます。また、クラスメソッドは継承されたクラスでも使えます。

class Student(Person):

    def __init__(self, name, age, school):

        super().__init__(name, age)

        self.school = school

 

    @classmethod

    def from_birth_year(cls, name, birth_year, school):

        age = 2023 - birth_year

        return cls(name, age, school)

 

s1 = Student("Charlie", 18, "Tokyo University")

s2 = Student.from_birth_year("David", 2005, "Tokyo High School")

print(s1.name, s1.age, s1.school) # Charlie 18 Tokyo University

print(s2.name, s2.age, s2.school) # David 18 Tokyo High School

このように、クラスメソッドを使うと、継承したクラスでも親クラスと同じようにインスタンスを作ることができます。

(15)compile()

引数に指定されたソースコード(文字列やバイト列)をコードオブジェクトに変換して返します。コードオブジェクトとは、Pythonインタプリタが実行できる形式のコードのことです。compile関数は、ソースコードを動的に評価したり、ファイルに保存したりするときに使われます。

# 引数にはソースコード、ファイル名、モードを指定する

# モードは、'exec'(文の列)、'eval'(式)、'single'(対話的な式)のいずれか

code = compile("x = 3\ny = 4\nprint(x + y)", "<string>", "exec") # 文の列をコードオブジェクトに変換

exec(code) # コードオブジェクトを実行する

# 7

 

code = compile("x * y", "<string>", "eval") # 式をコードオブジェクトに変換

x = 3

y = 4

result = eval(code) # コードオブジェクトを評価する

print(result) # 12

 

code = compile("x + y\n", "<string>", "single") # 対話的な式をコードオブジェクトに変換

x = 3

y = 4

exec(code) # コードオブジェクトを実行する

# 7

  • 注意点
    compile関数は、ソースコードをコードオブジェクトに変換するだけで、実際に実行することはできません。コードオブジェクトを実際に実行するには、exec関数やeval関数を使います。

code = compile("print('Hello')", "<string>", "exec") # 文をコードオブジェクトに変換

code # <code object <module> at 0x7f9f5c0a6c90, file "<string>", line 1>

code() # コードオブジェクトは呼び出し可能ではない

# TypeError: 'code' object is not callable

 

exec(code) # コードオブジェクトを実行する

# Hello

この関数を知らないと…
ソースコードを動的に評価するときに、exec関数やeval関数に直接渡してしまいます。これはセキュリティ上のリスクがあり、パフォーマンスに影響する可能性があります。

# exec関数に直接ソースコードを渡す

exec("x = 3\ny = 4\nprint(x + y)") # 7

 

# eval関数に直接ソースコードを渡す

x = 3

y = 4

result = eval("x * y") # 12

compile関数を使うと、ソースコードを事前にコードオブジェクトに変換しておくことができます。これは、同じソースコードを繰り返し実行する場合に効率的です。また、compile関数にはオプション引数として最適化レベルやフラグを指定することができます。これにより、ソースコードの構文チェックやデバッグ情報の削除などを行うことができます。

# compile関数を使ってソースコードをコードオブジェクトに変換

code = compile("x = 3\ny = 4\nprint(x + y)", "<string>", "exec")

exec(code) # 7

 

# オプション引数を指定してコードオブジェクトを作る

# optimize=2 は最適化レベルを最大にする

# dont_inherit=True は現在のスコープのフラグを無視する

code = compile("x = 3\ny = 4\nprint(x + y)", "<string>", "exec", optimize=2, dont_inherit=True)

exec(code) # 7

(16)complex()

引数に指定された実数部と虚数部から複素数を作って返します。複素数とは、実数と虚数の和で表される数のことです。虚数とは、平方根が負の数になる数のことで、iという記号で表されます。例えば、2 + 3iは複素数で、2は実数部、3は虚数部です。

# 引数には実数部と虚数部を指定する

c = complex(2, 3) # 2 + 3i

print(c) # (2+3j)

print(c.real) # 2.0

print(c.imag) # 3.0

 

# 引数が一つの場合、実数部として扱われる

c = complex(5) # 5 + 0i

print(c) # (5+0j)

 

# 引数が文字列の場合、複素数の表記として解釈される

c = complex("2+3j") # 2 + 3i

print(c) # (2+3j)

  • 注意点
    引数は数値か文字列でなければなりません。それ以外の型はエラーになります。

c = complex([1, 2]) # リストはエラーになる

# TypeError: complex() first argument must be a string or a number, not 'list'

引数が文字列の場合、複素数の表記として正しい形式でなければなりません。空白や不要な記号があるとエラーになります。

c = complex("2 + 3j") # 空白があるとエラーになる

# ValueError: complex() arg is a malformed string

 

c = complex("2+3i") # iではなくjでなければならない

# ValueError: complex() arg is a malformed string

この関数を知らないと…
複素数を扱うときに、実数部と虚数部を別々に管理してしまいます。これは複雑で、エラーが発生しやすいです。

# 実数部と虚数部を別々に管理する

real = 2

imag = 3

print(f"{real} + {imag}i") # 2 + 3i

 

# 複素数の演算をするときには、実数部と虚数部をそれぞれ計算する必要がある

real2 = 4

imag2 = 5

# (2 + 3i) + (4 + 5i) = (6 + 8i)

real_sum = real + real2

imag_sum = imag + imag2

print(f"{real_sum} + {imag_sum}i") # 6 + 8i

complex関数を使うと、複素数を一つのオブジェクトとして扱うことができます。

# 複素数を一つのオブジェクトとして扱う

c1 = complex(2, 3) # 2 + 3i

print(c1) # (2+3j)

 

# 複素数の演算をするときには、オブジェクト同士の演算でよい

c2 = complex(4, 5) # 4 + 5i

# (2 + 3i) + (4 + 5i) = (6 + 8i)

c_sum = c1 + c2

print(c_sum) # (6+8j)

(17)delattr()

引数に指定されたオブジェクトから、名前に対応する属性を削除します。属性とは、オブジェクトに紐づけられた変数や関数のことです。

class Person:

    def __init__(self, name, age):

        self.name = name # 属性

        self.age = age # 属性

 

    def greet(self): # 属性

        print(f"Hello, I'm {self.name}.")

 

p = Person("Alice", 25) # オブジェクトを作る

p.greet() # Hello, I'm Alice.

print(p.age) # 25

 

delattr(p, "age") # オブジェクトから属性を削除する

print(p.age) # 属性がなくなったのでエラーになる

# AttributeError: 'Person' object has no attribute 'age'

  • 注意点
    引数にはオブジェクトと属性の名前を指定する必要があります。属性の値やオブジェクトの属性ではなく、属性の名前を文字列で渡さなければなりません。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 25)

delattr(p, p.age) # 属性の値ではなく、属性の名前を渡さなければならない

# TypeError: attribute name must be string

 

delattr(p, p.name) # オブジェクトの属性ではなく、属性の名前を渡さなければならない

# TypeError: attribute name must be string

こういうときに便利
delattr関数は、オブジェクトから属性を削除することに特化した関数であるため、コードの意図を明確にすることに役立ちます。
del文を使う事もできますが、del文はオブジェクトから属性を削除するだけでなく、変数やリストの要素なども削除できるため、delattr関数はより特化的な関数として扱うことができます。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 25)

del p.age # del文を使ってオブジェクトから属性を削除する

print(p.age) # 属性がなくなったのでエラーになる

# AttributeError: 'Person' object has no attribute 'age'

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 25)

delattr(p, "age") # delattr関数を使ってオブジェクトから属性を削除する

print(p.age) # 属性がなくなったのでエラーになる

# AttributeError: 'Person' object has no attribute 'age'

(18)dict()

引数に指定されたキーと値のペアから辞書を作って返します。

# 引数にはキーと値のペアを指定する

d = dict(name="Alice", age=25) # キーワード引数で指定する

print(d) # {'name': 'Alice', 'age': 25}

 

d = dict([("name", "Alice"), ("age", 25)]) # イテラブルオブジェクトで指定する

print(d) # {'name': 'Alice', 'age': 25}

 

d = dict({"name": "Alice", "age": 25}) # 既存の辞書で指定する

print(d) # {'name': 'Alice', 'age': 25}

  • 注意点
    引数はキーと値のペアでなければなりません。キーと値のペアがない場合や、キーが重複している場合はエラーになります。

d = dict(3) # キーと値のペアがないとエラーになる

# TypeError: cannot convert dictionary update sequence element #0 to a sequence

 

d = dict(name="Alice", name="Bob") # キーが重複しているとエラーになる

# TypeError: dict() got multiple values for keyword argument 'name'

この関数を知らないと…
辞書を作るときに、リテラル表記を使ってしまいます。リテラル表記とは、辞書を{}で囲んで、キーと値のペアを:で区切って表す方法のことです。リテラル表記は、辞書を直接記述するときに便利ですが、キーと値のペアを動的に生成するときには不便です。

# リテラル表記を使って辞書を作る

d = {"name": "Alice", "age": 25}

print(d) # {'name': 'Alice', 'age': 25}

 

# キーと値のペアを動的に生成するときには不便

keys = ["name", "age"]

values = ["Alice", 25]

d = {} # 空の辞書を作る

for i in range(len(keys)): # インデックスを使ってループする

    d[keys[i]] = values[i] # キーと値のペアを追加する

print(d) # {'name': 'Alice', 'age': 25}

dict関数を使うと、キーと値のペアを引数として渡すことができます。これは、キーと値のペアを動的に生成するときに便利です。

# dict関数を使って辞書を作る

d = dict(name="Alice", age=25)

print(d) # {'name': 'Alice', 'age': 25}

 

# キーと値のペアを動的に生成するときに便利

keys = ["name", "age"]

values = ["Alice", 25]

d = dict(zip(keys, values)) # zip関数でキーと値のペアを作る

print(d) # {'name': 'Alice', 'age': 25}

(19)dir()

引数に指定したオブジェクトの属性やメソッドの名前をリストとして返します。引数を省略した場合は、現在のローカルスコープの名前をリストとして返します。

class Sample:

    def __init__(self, name):

        self.name = name

 

    def hello(self):

        print(f"Hello, {self.name}!")

 

sample = Sample("Bing")

print(dir(sample))

# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'hello', 'name']

 

print(dir())

# ['Sample', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sample']

  • 注意点
    dir関数はオブジェクトの属性やメソッドの名前をリストとして返しますが、そのリストは必ずしも完全ではありません。オブジェクトが __dir__() を提供しない場合、その型オブジェクトと、定義されていればオブジェクトの __dict__ 属性から、できるだけ情報を集めようとするためです。

この関数を知らないと…
オブジェクトの属性やメソッドを調べるときに、help関数やインターネットで検索するなどの手間がかかります。dir関数を使うと、簡単にオブジェクトの属性やメソッドの名前を確認できます。

(20)divmod()

引数に指定した2つの数値の商と余りをタプルとして返します。引数は整数または浮動小数点数でなければなりません。

print(divmod(7, 3))

# (2, 1)

 

print(divmod(7.5, 3))

# (2.0, 1.5)

  • 注意点
    引数のどちらかが浮動小数点数の場合は、商と余りも浮動小数点数になります。また、引数のどちらかが0の場合は、ZeroDivisionErrorが発生します。

この関数を知らないと…
商と余りを求めるときに、/や%などの演算子を使って別々に計算する必要があります。divmod関数を使うと、一度に商と余りを求めることができます。

x = 7

y = 3

quotient = x // y

remainder = x % y

result = (quotient, remainder)

print(result)

# (2, 1)

divmod関数を使うと以下のように書くことができます。

x = 7

y = 3

result = divmod(x, y)

print(result)

# (2, 1)

(21)enumerate()

引数に指定したイテラブルオブジェクトの要素とインデックスをタプルとして返すイテレータを作成します。インデックスは0から始まりますが、startパラメータで変更することができます。

fruits = ["apple", "banana", "cherry"]

for i, fruit in enumerate(fruits):

    print(i, fruit)

# 0 apple

# 1 banana

# 2 cherry

 

for i, fruit in enumerate(fruits, start=1):

    print(i, fruit)

# 1 apple

# 2 banana

# 3 cherry

  • 注意点
    引数のイテラブルオブジェクトが空の場合は、空のイテレータを返します。また、引数のイテラブルオブジェクトが変更されると、イテレータの挙動は保証されません。

この関数を知らないと…
イテラブルオブジェクトの要素とインデックスを同時に取得するときに、ループの中でインデックスを管理するために別の変数を用意してインクリメントする必要があります。

arr = ["apple", "banana", "cherry"]

i = 0

for x in arr:

    print(i, x)

    i += 1

 

enumerate関数を使うと、簡単にイテラブルオブジェクトの要素とインデックスをタプルとして取得できます。

arr = ["apple", "banana", "cherry"]

for i, x in enumerate(arr):

    print(i, x)

 

(22)eval()

引数に与えられた文字列をPythonの式として評価し、その結果を返す関数です。

x = 2

y = 3

result = eval("x + y")

print(result) # 5

  • 注意点
    引数には式だけを指定できます。文や複合文を指定するとエラーになります。

eval("print('Hello')") # SyntaxError: invalid syntax

引数には信頼できる文字列だけを指定してください。悪意のあるコードを実行される可能性があります。

eval("os.system('rm -rf /')") # 危険!

引数に変数や関数を含む文字列を指定する場合、その変数や関数がスコープ内に存在する必要があります。存在しない場合はエラーになります。

def square(x):

    return x ** 2

 

eval("square(4)") # 16

 

eval("cube(3)") # NameError: name 'cube' is not defined

この関数を知らないと…
文字列として表された式を動的に評価する必要がある場合に、手動でパースしたり、exec関数を使って無駄な処理を実行してしまいます。

# 文字列をパースして計算する例

expression = "2 * 3 + 4"

tokens = expression.split()

result = int(tokens[0]) * int(tokens[2]) + int(tokens[4])

print(result) # 10

 

# exec関数を使って評価する例

expression = "2 * 3 + 4"

exec(f"result = {expression}")

print(result) # 10

eval関数を使うと以下のように書くことができます。

expression = "2 * 3 + 4"

result = eval(expression)

print(result) # 10

(23)exec()

引数に与えられた文字列をPythonの文として実行する関数です。

code = """

x = 2

y = 3

print(x + y)

"""

exec(code) # 5

  • 注意点
    引数には文や複合文を指定できますが、式は指定できません。式を指定するとエラーになります。

exec("x + y") # SyntaxError: Missing parentheses in call to 'exec'

引数には信頼できる文字列だけを指定してください。悪意のあるコードを実行される可能性があります。

exec("os.system('rm -rf /')") # 危険!

引数に変数や関数を含む文字列を指定する場合、その変数や関数がスコープ内に存在する必要があります。存在しない場合はエラーになります。

def square(x):

    return x ** 2

 

exec("print(square(4))") # 16

 

exec("print(cube(3))") # NameError: name 'cube' is not defined

exec関数は戻り値を返しません。Noneが返されます。

result = exec("print('Hello')")

print(result) # None

exec関数はグローバルやローカルの名前空間を指定することができます。名前空間は辞書として渡します。

exec("print(x + y)", {"x": 2, "y": 3}) # 5

 

z = 4

exec("print(x + y + z)", {"x": 2, "y": 3}, {"z": z}) # 9

この関数を知らないと…
文字列として表された文を動的に実行する必要がある場合に、eval関数を使って無効な式を評価したり、手動でパースしたりしてしまいます。

# eval関数を使って文を評価する例

code = "print('Hello')"

eval(code) # SyntaxError: invalid syntax

 

# 文字列をパースして実行する例

code = "x = 2; y = 3; print(x + y)"

tokens = code.split(";")

for token in tokens:

    exec(token.strip()) # 5

exec関数を使うと以下のように書くことができます。

code = "x = 2; y = 3; print(x + y)"

exec(code) # 5

(24)filter()

引数に与えられたイテラブルオブジェクトから、条件に合う要素だけを取り出す関数です。

def is_even(x):

    return x % 2 == 0

 

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

evens = filter(is_even, numbers)

print(list(evens)) # [2, 4, 6]

  • 注意点
    引数には関数とイテラブルオブジェクトを指定します。関数はイテラブルオブジェクトの各要素を引数にとり、真偽値を返すものでなければなりません。

def add_one(x):

    return x + 1

 

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

result = filter(add_one, numbers) # TypeError: 'int' object is not iterable

filter関数はイテレータオブジェクトを返します。リストやタプルなどに変換するには、list()やtuple()などの関数を使います。

def is_even(x):

    return x % 2 == 0

 

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

evens = filter(is_even, numbers)

print(evens) # <filter object at 0x000001E8B0A9F7F0>

print(list(evens)) # [2, 4, 6]

引数の関数には無名関数(lambda式)を使うこともできます。これはコードを簡潔に書くために便利です。

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

evens = filter(lambda x: x % 2 == 0, numbers)

print(list(evens)) # [2, 4, 6]

この関数を知らないと…
イテラブルオブジェクトから条件に合う要素を取り出す場合に、for文やif文を使って手動でフィルタリングしたり、リスト内包表記を使って冗長なコードを書いてしまいます。

# for文とif文を使ってフィルタリングする例

def is_even(x):

    return x % 2 == 0

 

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

evens =

for n in numbers:

    if is_even(n):

        evens.append(n)

print(evens) # [2, 4, 6]

 

# リスト内包表記を使ってフィルタリングする例

def is_even(x):

    return x % 2 == 0

 

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

evens = [n for n in numbers if is_even(n)]

print(evens) # [2, 4, 6]

filter関数を使うと以下のように書くことができます。

def is_even(x):

    return x % 2 == 0

 

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

evens = filter(is_even, numbers)

print(list(evens)) # [2, 4, 6]

(25)float()

引数に指定した数値または文字列を浮動小数点数に変換して返します。

x = float(10) # 整数を浮動小数点数に変換

print(x) # 10.0

y = float("3.14") # 文字列を浮動小数点数に変換

print(y) # 3.14

z = float("nan") # 特殊な値を表す文字列も変換できる

print(z) # nan

  • 注意点
    引数を省略した場合は0.0を返します。

x = float()

print(x) # 0.0

引数に浮動小数点数を表すことができない文字列を指定した場合はValueErrorを発生させます。

x = float("abc") # エラー

この関数を知らないと…
数値の計算や比較を行う際に型の不一致によるエラーやバグを引き起こす可能性があります。

x = 3

y = "3.14"

z = x + y

print(z)

# TypeError: unsupported operand type(s) for +: 'int' and 'str'

float関数を使うと以下のように書くことができます。

x = 3

y = "3.14"

z = x + float(y)

print(z) # 6.14

(26)format()

引数に指定した値を書式化した文字列を返します。書式化の方法は、第二引数に指定することができます。

x = format(12345, ",") # 3桁ごとにカンマを入れる

print(x) # 12,345

y = format(0.1234, ".2%") # パーセント表示にして小数点以下2桁にする

print(y) # 12.34%

z = format(255, "x") # 16進数に変換する

print(z) # ff

  • 注意点
    第二引数を省略した場合は、str関数と同じ結果を返します。

x = format(12345)

print(x) # 12345

第二引数に無効な書式を指定した場合はValueErrorを発生させます。

x = format(12345, "a") # エラー

この関数を知らないと…
文字列の連結やフォーマットを行う際に+や%などの演算子を使って複雑なコードを書いてしまいます。

name = "Alice"

age = 20

message = "Hello, my name is " + name + " and I am " + str(age) + " years old."

print(message)

# Hello, my name is Alice and I am 20 years old.

format関数を使うと以下のように書くことができます。

name = "Alice"

age = 20

message = "Hello, my name is {} and I am {} years old.".format(name, age)

print(message)

# Hello, my name is Alice and I am 20 years old.

(27)frozenset()

引数に指定したイテラブルオブジェクトから、要素の追加や削除ができない集合を作成して返します。

x = frozenset([1, 2, 3, 4]) # リストからfrozensetを作成

print(x) # frozenset({1, 2, 3, 4})

y = frozenset("hello") # 文字列からfrozensetを作成

print(y) # frozenset({'h', 'e', 'l', 'o'})

z = frozenset() # 空のfrozensetを作成

print(z) # frozenset()

  • 注意点
    frozensetはイミュータブルなオブジェクトなので、要素の追加や削除を行おうとするとAttributeErrorを発生させます。

x = frozenset([1, 2, 3, 4])

x.add(5) # エラー

x.remove(4) # エラー

frozensetは集合演算を行うことができます。集合演算とは、和集合、積集合、差集合、対称差集合などの演算のことです。

x = frozenset([1, 2, 3, 4])

y = frozenset([3, 4, 5, 6])

z = x | y # 和集合

print(z) # frozenset({1, 2, 3, 4, 5, 6})

w = x & y # 積集合

print(w) # frozenset({3, 4})

v = x - y # 差集合

print(v) # frozenset({1, 2})

u = x ^ y # 対称差集合

print(u) # frozenset({1, 2, 5, 6})

この関数を知らないと…
イテラブルオブジェクトから重複を除くためにset関数を使っても、変更可能なオブジェクトとして扱われるために、辞書のキーや集合の要素になることができません。

s = set({1, 2, 3, 4, 5})

d = {s: "Hello"}

print(d)

# TypeError: unhashable type: 'set'

frozenset関数を使うと以下のように書くことができます。

s = frozenset({1, 2, 3, 4, 5})

d = {s: "Hello"}

print(d)

# {frozenset({1, 2, 3, 4, 5}): 'Hello'}

(28) getattr()

オブジェクトの属性を取得する関数です。第一引数にオブジェクト、第二引数に属性名を文字列で指定します。第三引数にデフォルト値を指定することもできます。属性が存在しない場合には、デフォルト値を返すか、AttributeErrorを発生させます。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 20)

print(getattr(p, "name")) # Alice

print(getattr(p, "age")) # 20

print(getattr(p, "gender", "unknown")) # unknown

print(getattr(p, "height")) # AttributeError: 'Person' object has no attribute 'height'

  • 注意点
    属性名は文字列で指定する必要があります。変数や式を使うことはできません。

attr = "name"

print(getattr(p, attr)) # Alice

print(getattr(p, "na" + "me")) # Alice

print(getattr(p, 3)) # TypeError: getattr(): attribute name must be string

この関数を知らないと…
オブジェクトの属性を動的に取得することができません。例えば、ユーザーからの入力に応じてオブジェクトの属性を表示するようなプログラムを作る場合には、getattr関数が便利です。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 20)

while True:

    attr = input("Enter an attribute name: ")

    if attr == "quit":

        break

    value = getattr(p, attr, None)

    if value is None:

        print("No such attribute")

    else:

        print(value)

(29) globals()

現在のグローバルスコープにある変数や関数などのシンボルを辞書として返す関数です。この辞書は実行時に変更可能であり、グローバルスコープに影響を与えます。

x = 10

y = 20

def foo():

    print("Hello")

 

g = globals()

print(g["x"]) # 10

print(g["y"]) # 20

print(g["foo"]) # <function foo at 0x000001E0F8C0A1F0>

g["x"] = 100 # グローバル変数xの値を変更

g["z"] = 30 # グローバル変数zを追加

g["bar"] = lambda: print("World") # グローバル関数barを追加

print(x) # 100

print(z) # 30

foo() # Hello

bar() # World

  • 注意点
    globals関数は辞書を返すので、その辞書に対して変更を加えると、グローバルシンボルテーブルにも反映されます。

# グローバル変数を定義

x = 10

y = 20

 

# globals関数の戻り値を変数に代入

g = globals()

 

# gに対して変更を加える

g['x'] = 100

g['z'] = 30

 

# グローバルシンボルテーブルが変更されていることを確認

print(x) # 100

print(z) # 30

 

この関数を知らないと…
グローバルスコープにあるシンボルを動的に参照したり、変更したり、追加したりすることができません。例えば、ユーザーからの入力に応じてグローバル変数の値を表示したり、グローバル関数を呼び出したりするようなプログラムを作る場合には、globals関数が便利です。

x = 10

y = 20

def foo():

    print("Hello")

 

def bar():

    print("World")

 

while True:

    name = input("Enter a global symbol name: ")

    if name == "quit":

        break

    g = globals()

    if name in g:

        value = g[name]

        if callable(value):

            value() # グローバル関数を呼び出す

        else:

            print(value) # グローバル変数の値を表示する

    else:

        print("No such symbol")

(30) hasattr()

オブジェクトが指定した属性を持っているかどうかを真偽値で返す関数です。第一引数にオブジェクト、第二引数に属性名を文字列で指定します。属性が存在する場合にはTrueを返し、存在しない場合にはFalseを返します。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 20)

print(hasattr(p, "name")) # True

print(hasattr(p, "age")) # True

print(hasattr(p, "gender")) # False

print(hasattr(p, "height")) # False

  • 注意点
    属性名は文字列で指定する必要があります。変数や式を使うことはできません。

attr = "name"

print(hasattr(p, attr)) # True

print(hasattr(p, "na" + "me")) # True

print(hasattr(p, 3)) # TypeError: hasattr(): attribute name must be string

この関数を知らないと…
オブジェクトの属性の有無を確認するために、例外処理を書く必要があり、コードが冗長になります。例えば、オブジェクトの属性を表示する前に、その属性が存在するかどうかをチェックするようなプログラムを作る場合には、hasattr関数が便利です。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 20)

while True:

    attr = input("Enter an attribute name: ")

    if attr == "quit":

        break

    if hasattr(p, attr):

        print(getattr(p, attr))

    else:

        print("No such attribute")

(31)hash()

引数に渡したオブジェクトのハッシュ値を返します。ハッシュ値とは、オブジェクトの内容や識別子に基づいて計算される整数のことです。ハッシュ値は、辞書型のキーの比較や集合型の要素の検索などに用いられます。

# 文字列のハッシュ値

s = "Hello, world!"

print(hash(s)) # 5980307948332718216

 

# 数値のハッシュ値

n = 42

print(hash(n)) # 42

 

# リストのハッシュ値

l = [1, 2, 3]

print(hash(l)) # TypeError: unhashable type: 'list'

  • 注意点
    ハッシュ値は、オブジェクトの内容が変更されないことが保証されている場合にのみ有効です。そのため、ミュータブルなオブジェクト(内容を変更できるオブジェクト)はハッシュ可能ではありません。例えば、リストや辞書はハッシュ不可能なオブジェクトです。ハッシュ不可能なオブジェクトに対してhash関数を呼び出すと、TypeErrorが発生します。

この関数を知らないと…
オブジェクトの同一性や等価性を判定するのに、==やisなどの演算子を使ってしまいます。しかし、これらの演算子は、オブジェクトの内容や識別子を直接比較するので、時間やメモリの効率が悪くなります。

# 二つの文字列を比較

s1 = "Hello, world!"

s2 = "Hello, world!"

print(s1 == s2) # True

print(s1 is s2) # False

 

# 二つの数値を比較

n1 = 42

n2 = 42

print(n1 == n2) # True

print(n1 is n2) # True

hash関数を使うと以下のように書くことができます。

# 二つの文字列のハッシュ値を比較

s1 = "Hello, world!"

s2 = "Hello, world!"

print(hash(s1) == hash(s2)) # True

 

# 二つの数値のハッシュ値を比較

n1 = 42

n2 = 42

print(hash(n1) == hash(n2)) # True

(32)help()

引数(オブジェクト)に関するヘルプ情報を表示します。引数がない場合は、対話的なヘルプシステムを起動します。ヘルプ情報には、オブジェクトの型、メソッド、属性、ドキュメントなどが含まれます。

# 文字列に関するヘルプ情報を表示する

help(str)

 

# 対話的なヘルプシステムを起動する

help()

  • 注意点
    ヘルプ情報は、オブジェクトの定義に基づいて生成されます。そのため、オブジェクトがカスタマイズされている場合や、ドキュメントが不十分な場合は、ヘルプ情報が正確でない場合があります。

# カスタマイズされたクラスのヘルプ情報を表示する

class MyList(list):

    def __init__(self, *args):

        super().__init__(*args)

        self.name = "MyList"

 

help(MyList)

# ヘルプ情報には、name属性についての説明がない

この関数を知らないと…
オブジェクトに関する情報を得るために、インターネットで検索したり、ソースコードを読んだりする必要があります。しかし、help関数を使えば、簡単にオブジェクトのヘルプ情報を確認することができます。

# インターネットで検索する

# https://docs.python.org/ja/3/library/functions.html#abs

 

# ソースコードを読む

# https://github.com/python/cpython/blob/master/Python/bltinmodule.c#L2140

 

# help関数を使う

help(abs)

(33)hex()

引数(整数)を16進数の文字列に変換して返します。16進数とは、0から9までの数字とAからFまでのアルファベットを使って数を表現する方法です。16進数の文字列は、先頭に"0x"が付きます。

n = 255

assert hex(n) == "0xff"

  • 注意点
    hex関数は、整数以外の数値に対しては使えません。浮動小数点数複素数に対しては、hex関数を使うとエラーが発生します。浮動小数点数複素数を16進数に変換するには、別の方法を使う必要があります。

# 浮動小数点数に対してhex関数を使うとエラーが発生する

f = 3.14

hex(f)

# TypeError: 'float' object cannot be interpreted as an integer

 

# 複素数に対してhex関数を使うとエラーが発生する

c = 1 + 2j

hex(c)

# TypeError: can't convert complex to int

この関数を知らないと…
整数を16進数に変換する際に、自分で計算したり、フォーマット文字列を使ったりする必要があります。しかし、hex関数を使えば、簡単に整数を16進数に変換することができます。

# 自分で計算する

n = 255

digits = "0123456789abcdef"

hex_str = ""

while n > 0:

    hex_str = digits[n % 16] + hex_str

    n //= 16

hex_str = "0x" + hex_str

assert hex_str == "0xff"

 

# フォーマット文字列を使う

n = 255

hex_str = f"0x{n:x}"

assert hex_str == "0xff"

 

# hex関数を使う

n = 255

hex_str = hex(n)

assert hex_str == "0xff"

(34)id()

引数(オブジェクト)の識別子を返します。識別子とは、オブジェクトがメモリ上に存在する場所を表す数値です。識別子は、オブジェクトのライフタイム中に一定であり、同じオブジェクトに対しては常に同じ値を返します。

s = "Hello"

assert id(s) == 140664372249680 # 識別子は実行環境によって異なる場合があります

  • 注意点
    識別子は、オブジェクトの内容や型とは関係ありません。同じ内容や型のオブジェクトでも、異なる識別子を持つ場合があります。識別子は、オブジェクトの同一性を判定するために使われますが、オブジェクトの等価性を判定するために使われることはありません。

# 同じ内容のオブジェクトでも、異なる識別子を持つ場合がある

s1 = "Hello"

s2 = "Hello"

assert s1 == s2 # True

assert id(s1) != id(s2) # True

 

# 同じ型のオブジェクトでも、異なる識別子を持つ場合がある

n1 = 1

n2 = 1

assert n1 == n2 # True

assert id(n1) != id(n2) # True

こういうときに便利
オブジェクトの識別値を使って、オブジェクトのコピーの種類を判別することができます。オブジェクトのコピーには、浅いコピーと深いコピーの二種類があります。浅いコピーは、オブジェクトの参照をコピーするだけで、オブジェクトの内容は共有されます。深いコピーは、オブジェクトの内容を完全にコピーするので、オリジナルとコピーは独立したオブジェクトになります。例えば、以下のコードを見てみましょう。

# リストを定義

l = [1, 2, 3]

 

# 浅いコピーを作成

import copy

l1 = copy.copy(l)

 

# 深いコピーを作成

l2 = copy.deepcopy(l)

 

# オリジナルとコピーの識別値を比較

print(id(l) == id(l1)) # False

print(id(l) == id(l2)) # False

 

# オリジナルとコピーの要素の識別値を比較

print(id(l[0]) == id(l1[0])) # True

print(id(l[0]) == id(l2[0])) # True

 

# オリジナルの要素を変更

l[0] = 100

 

# コピーの要素が変更されたか確認

print(l1[0]) # 100

print(l2[0]) # 1

このコードでは、リストlを浅いコピーと深いコピーに分けています。オリジナルとコピーの識別値は異なりますが、オリジナルと浅いコピーの要素の識別値は同じです。これは、浅いコピーがオリジナルの参照をコピーしていることを示しています。そのため、オリジナルの要素を変更すると、浅いコピーの要素も変更されます。一方、オリジナルと深いコピーの要素の識別値は同じですが、オリジナルの要素を変更しても、深いコピーの要素は変更されません。このように、id関数を使って、オブジェクトのコピーの種類を判別することができます。

(35)input()

引数(文字列)を標準出力に表示し、ユーザーからの入力を受け取って返します。引数がない場合は、何も表示しません。ユーザーが入力した文字列は、改行文字を除いて返されます。

# 引数を指定する

name = input("What is your name? ")

print(f"Hello, {name}!")

 

# 引数を指定しない

s = input()

print(f"You entered: {s}")

  • 注意点
    input関数は、ユーザーが入力した文字列をそのまま返します。そのため、数値や真偽値などの他の型に変換する必要がある場合は、適切な関数を使ってキャストする必要があります。また、ユーザーが入力をキャンセルした場合や、無効な入力をした場合は、エラーが発生する可能性があります。そのため、input関数を使う際は、エラー処理を行うことが推奨されます。

# 数値に変換する

n = input("Enter a number: ")

n = int(n) # キャストする

print(f"The square of {n} is {n**2}")

 

# 真偽値に変換する

b = input("Enter True or False: ")

b = bool(b) # キャストする

print(f"The opposite of {b} is {not b}")

 

# エラー処理を行う

try:

    s = input("Enter something: ")

    print(f"You entered: {s}")

except EOFError:

    print("You cancelled the input")

except Exception as e:

    print(f"An error occurred: {e}")

この関数を知らないと…
ユーザーからの入力を受け取るために、標準入力を直接読み込んだり、GUIを作成したりする必要があります。しかし、input関数を使えば、簡単にユーザーからの入力を受け取ることができます。

# 標準入力を直接読み込む

import sys

s = sys.stdin.readline()

print(f"You entered: {s}")

 

# GUIを作成する

import tkinter as tk

window = tk.Tk()

entry = tk.Entry(window)

entry.pack()

button = tk.Button(window, text="Submit", command=lambda: print(f"You entered: {entry.get()}"))

button.pack()

window.mainloop()

 

# input関数を使う

s = input("Enter something: ")

print(f"You entered: {s}")

(36)int()

引数(オブジェクト)を整数に変換して返します。引数が数値の場合は、その数値を整数に切り捨てます。引数が文字列の場合は、その文字列を整数として解釈します。引数がない場合は、0を返します。第二引数(基数)を指定すると、その基数に従って引数を整数に変換します。基数とは、数を表現する際に使う記号の種類を表す数値です。基数は、2から36までの整数で指定できます。

# 数値を整数に変換する

f = 3.14

assert int(f) == 3

 

# 文字列を整数に変換する

s = "123"

assert int(s) == 123

 

# 引数を指定しない

assert int() == 0

 

# 基数を指定する

s = "ff"

assert int(s, 16) == 255

  • 注意点
    int関数は、引数が整数に変換できる場合にのみ使えます。引数が整数に変換できない場合は、エラーが発生します。整数に変換できない場合とは、以下のような場合です。
    • 引数が数値でも文字列でもない場合
    • 引数が文字列であっても、整数として解釈できない場合
    • 引数が文字列であっても、基数として指定した値に対応しない場合

# 引数が数値でも文字列でもない場合

l = [1, 2, 3]

int(l)

# TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

 

# 引数が文字列であっても、整数として解釈できない場合

s = "Hello"

int(s)

# ValueError: invalid literal for int() with base 10: 'Hello'

 

# 引数が文字列であっても、基数として指定した値に対応しない場合

s = "ff"

int(s, 2)

# ValueError: invalid literal for int() with base 2: 'ff'

この関数を知らないと…
整数に変換するために、自分で計算したり、正規表現を使ったりする必要があります。しかし、int関数を使えば、簡単に整数に変換することができます。

(37)isinstance()

引数(オブジェクト, クラス)が指定したクラスのインスタンスであるかどうかを真偽値で返します。第二引数には、クラスやクラスのタプルを指定できます。第二引数にクラスのタプルを指定した場合は、そのいずれかのクラスのインスタンスであるかどうかを判定します。

# クラスを定義する

class Animal:

    def __init__(self, name):

        self.name = name

 

class Dog(Animal):

    def __init__(self, name, breed):

        super().__init__(name)

        self.breed = breed

 

# クラスのインスタンスを作成する

a = Animal("Tom")

d = Dog("Bob", "Poodle")

 

# クラスのインスタンスであるかどうかを判定する

assert isinstance(a, Animal) == True

assert isinstance(d, Dog) == True

assert isinstance(d, Animal) == True # 継承関係にある場合もTrueになる

assert isinstance(a, Dog) == False

  • 注意点
    isinstance関数は、オブジェクトの型を判定するために使われますが、オブジェクトの内容や振る舞いを判定するために使われることはありません。オブジェクトの内容や振る舞いを判定するには、他の方法を使う必要があります。

# オブジェクトの内容を判定する

s = "Hello"

assert isinstance(s, str) == True # 型を判定する

assert s == "Hello" == True # 内容を判定する

 

# オブジェクトの振る舞いを判定する

l = [1, 2, 3]

assert isinstance(l, list) == True # 型を判定する

assert hasattr(l, "append") == True # メソッドを判定する

こういうときに便利…
isinstance関数は、オブジェクトの型に応じて処理を分岐させたいときに便利です。 例えば、関数の引数に複数の型のオブジェクトを受け付ける場合に、isinstance関数を使って型チェックを行うことができます。 以下のコードは、引数に文字列や数値、リストなどを受け取り、それぞれに応じたメッセージを出力する関数の例です。

def print_message(obj):

  if isinstance(obj, str):

    print("This is a string: " + obj)

  elif isinstance(obj, (int, float)):

    print("This is a number: " + str(obj))

  elif isinstance(obj, list):

    print("This is a list: " + str(obj))

  else:

    print("This is something else: " + str(obj))

 

print_message("Hello") # This is a string: Hello

print_message(3.14) # This is a number: 3.14

print_message([1, 2, 3]) # This is a list: [1, 2, 3]

print_message(True) # This is something else: True

isinstance関数は、第二引数にタプルを渡すことで、複数の型との比較ができます。 この例では、int型とfloat型のどちらかであれば、同じメッセージを出力しています。 また、isinstance関数は、サブクラスのインスタンスも真と判定します。 この例では、bool型はint型のサブクラスであるため、数値として扱われません。 このように、isinstance関数を使うと、オブジェクトの型に応じて処理を分岐させることができます。

(38)issubclass()

引数(クラス1, クラス2)が指定したクラスのサブクラスであるかどうかを真偽値で返します。サブクラスとは、他のクラスから継承したクラスのことです。第二引数には、クラスやクラスのタプルを指定できます。第二引数にクラスのタプルを指定した場合は、そのいずれかのクラスのサブクラスであるかどうかを判定します。

# クラスを定義する

class Animal:

    def __init__(self, name):

        self.name = name

 

class Dog(Animal):

    def __init__(self, name, breed):

        super().__init__(name)

        self.breed = breed

 

class Cat(Animal):

    def __init__(self, name, color):

        super().__init__(name)

        self.color = color

 

# クラスのサブクラスであるかどうかを判定する

assert issubclass(Dog, Animal) == True

assert issubclass(Cat, Animal) == True

assert issubclass(Dog, Cat) == False

assert issubclass(Dog, (Animal, Cat)) == True # タプルを指定する

  • 注意点
    issubclass関数は、クラスの継承関係を判定するために使われますが、クラスのインスタンス関係を判定するために使われることはありません。クラスのインスタンス関係を判定するには、isinstance関数を使う必要があります。

# クラスの継承関係を判定する

assert issubclass(Dog, Animal) == True

 

# クラスのインスタンス関係を判定する

d = Dog("Bob", "Poodle")

assert isinstance(d, Dog) == True

assert isinstance(d, Animal) == True

この関数を知らないと…
クラスの継承関係を判定するために、クラスの属性やメソッドを調べたり、ソースコードを読んだりする必要があります。しかし、issubclass関数を使えば、簡単にクラスの継承関係を判定することができます。

# クラスの属性やメソッドを調べる

assert hasattr(Dog, "breed") == True # Dogクラスにbreed属性がある

assert hasattr(Dog, "name") == True # Dogクラスにname属性がある

assert hasattr(Animal, "breed") == False # Animalクラスにbreed属性がない

assert hasattr(Animal, "name") == True # Animalクラスにname属性がある

 

# ソースコードを読む

# class Dog(Animal): # DogクラスはAnimalクラスを継承している

 

# issubclass関数を使う

assert issubclass(Dog, Animal) == True

(39)iter()

引数(オブジェクト)をイテレータに変換して返します。イテレータとは、要素を一つずつ返すことができるオブジェクトのことです。引数には、イテラブルなオブジェクトや呼び出し可能なオブジェクト(関数やメソッドなど)を指定できます。第二引数(終了値)を指定すると、第一引数の呼び出し結果が第二引数と等しくなったときに、イテレータが終了するようになります。

# 呼び出し可能なオブジェクトをイテレータに変換する

import random

it = iter(random.random, 0.5) # random.randomは0から1までの乱数を返す関数

assert next(it) < 0.5 # イテレータから要素を一つ取り出す

assert next(it) < 0.5

# assert next(it) # イテレータが終了した

  • 注意点
    iter関数は、オブジェクトをイテレータに変換するために使われますが、イテレータをイテラブルに変換するために使われることはありません。イテレータをイテラブルに変換するには、他の方法を使う必要があります。

# イテレータをイテラブルに変換する

it = iter([1, 2, 3])

l = list(it) # リストに変換する

print(l) # [1, 2, 3]

この関数を知らないと…
オブジェクトをイテレータに変換するために、自分でイテレータクラスを定義したり、ジェネレータを使ったりする必要があります。しかし、iter関数を使えば、簡単にオブジェクトをイテレータに変換することができます。

# 自分でイテレータクラスを定義する

class MyIterator:

    def __init__(self, iterable):

        self.iterable = iterable

        self.index = 0

 

    def __next__(self):

        if self.index < len(self.iterable):

            value = self.iterable[self.index]

            self.index += 1

            return value

        else:

            raise StopIteration

 

l = [1, 2, 3]

it = MyIterator(l)

assert next(it) == 1

assert next(it) == 2

assert next(it) == 3

# assert next(it) # イテレータが終了した

 

# ジェネレータを使う

def my_iterator(iterable):

    for value in iterable:

        yield value

 

l = [1, 2, 3]

it = my_iterator(l)

assert next(it) == 1

assert next(it) == 2

assert next(it) == 3

# assert next(it) # イテレータが終了した

 

# iter関数を使う

l = [1, 2, 3]

it = iter(l)

assert next(it) == 1

assert next(it) == 2

assert next(it) == 3

# assert next(it) # イテレータが終了した

(40)len()

引数(オブジェクト)の長さを返します。長さとは、オブジェクトが持つ要素の数や文字の数などのことです。引数には、長さを持つことができるオブジェクトを指定できます。長さを持つことができるオブジェクトには、イテラブルなオブジェクトや文字列やバイト列などのように、要素や文字を順番に取り出すことができるオブジェクトが該当します。

# イテラブルなオブジェクトの長さを返す

l = [1, 2, 3]

assert len(l) == 3

 

# 文字列の長さを返す

s = "Hello"

assert len(s) == 5

 

# バイト列の長さを返す

b = b"Hello"

assert len(b) == 5

  • 注意点
    len関数は、オブジェクトの長さを返すために使われますが、オブジェクトの大きさや容量を返すために使われることはありません。オブジェクトの大きさや容量を返すには、他の方法を使う必要があります。

# オブジェクトの大きさを返す

import sys

l = [1, 2, 3]

assert len(l) == 3 # 長さを返す

assert sys.getsizeof(l) == 88 # バイト単位で大きさを返す

 

# オブジェクトの容量を返す

import array

a = array.array('i', [1, 2, 3])

assert len(a) == 3 # 長さを返す

assert a.itemsize == 4 # 一つの要素が占めるバイト数を返す

assert a.buffer_info()[1] == 3 # 実際に使われている要素の数を返す

assert a.buffer_info()[0] == 140664372249680 # メモリアドレスを返す

この関数を知らないと…
オブジェクトの長さを得るために、自分でカウントしたり、ループを使ったりする必要があります。しかし、len関数を使えば、簡単にオブジェクトの長さを得ることができます。

# 自分でカウントする

s = "Hello"

count = 0

for c in s:

    count += 1

assert count == 5

 

# ループを使う

s = "Hello"

count = 0

while s:

    s = s[1:]

    count += 1

assert count == 5

 

# len関数を使う

s = "Hello"

assert len(s) == 5

(41)list()

引数(イテラブルオブジェクト)からリストを作成します。

arr = list(range(5))

print(arr) # [0, 1, 2, 3, 4]

 

str = list("Hello")

print(str) # ['H', 'e', 'l', 'l', 'o']

  • 注意点
    引数がない場合には空のリストを返します。

arr = list()

print(arr) #

この関数を知らないと…
イテラブルオブジェクトをリストに変換する際に、for文やappendメソッドを使って無駄なコードを書いてしまいます。

arr =

for i in range(5):

    arr.append(i)

print(arr) # [0, 1, 2, 3, 4]

list関数を使うと以下のように書くことができます。

arr = list(range(5))

print(arr) # [0, 1, 2, 3, 4]

(42)locals()

現在のローカルスコープにある変数の辞書を返します。

def func():

    x = 1

    y = 2

    print(locals()) # {'x': 1, 'y': 2}

 

func()

  • 注意点
    グローバルスコープでは、locals()とglobals()は同じ辞書を返します。

x = 1

y = 2

print(locals()) # {'x': 1, 'y': 2, '__name__': '__main__', ...}

print(globals()) # {'x': 1, 'y': 2, '__name__': '__main__', ...}

この関数を知らないと…
ローカルスコープにある変数を確認する際に、個別にprint文を書いてしまいます。

def func():

    x = 1

    y = 2

    print(x) # 1

    print(y) # 2

 

func()

locals関数を使うと以下のように書くことができます。

def func():

    x = 1

    y = 2

    print(locals()) # {'x': 1, 'y': 2}

 

func()

(43)map()

第一引数(関数)を第二引数(イテラブルオブジェクト)の各要素に適用した結果を返します。

def square(x):

    return x ** 2

 

arr = [1, 2, 3, 4, 5]

result = map(square, arr)

print(list(result)) # [1, 4, 9, 16, 25]

  • 注意点
    map関数はイテレータを返すので、リストに変換するにはlist関数を使います。

def square(x):

    return x ** 2

 

arr = [1, 2, 3, 4, 5]

result = map(square, arr)

print(result) # <map object at 0x000001E8F1A6B9A0>

print(list(result)) # [1, 4, 9, 16, 25]

この関数を知らないと…
イテラブルオブジェクトの各要素に関数を適用する際に、for文やリスト内包表記を使った冗長なコードを書くことになります。

def square(x):

    return x ** 2

 

arr = [1, 2, 3, 4, 5]

result =

for x in arr:

    result.append(square(x))

print(result) # [1, 4, 9, 16, 25]

map関数を使うと以下のように書くことができます。

def square(x):

    return x ** 2

 

arr = [1, 2, 3, 4, 5]

result = map(square, arr)

print(list(result)) # [1, 4, 9, 16, 25]

(44)max()

引数(イテラブルオブジェクト)の中で最大の要素を返します。

arr = [1, 2, 3, 4, 5]

print(max(arr)) # 5

 

str = "Hello"

print(max(str)) # o

  • 注意点
    引数が空の場合にはValueErrorを発生させます。

arr =

print(max(arr)) # ValueError: max() arg is an empty sequence

この関数を知らないと…
イテラブルオブジェクトの中で最大の要素を探す際に、for文やif文を使った冗長なコードを書くことになります。

arr = [1, 2, 3, 4, 5]

max = arr[0]

for x in arr:

    if x > max:

        max = x

print(max) # 5

max関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 5]

print(max(arr)) # 5

(45)memoryview()

引数(バイト列オブジェクト)のメモリビューを返します。メモリビューは、オブジェクトの内部データを直接アクセスすることができるオブジェクトです。

arr = bytearray(b"Hello")

mv = memoryview(arr)

print(mv) # <memory at 0x000001E8F1A6B9A0>

print(mv[0]) # 72

print(mv[-1]) # 111

  • 注意点
    メモリビューはイミュータブルなオブジェクトではなく、元のオブジェクトのデータを変更することができます。

arr = bytearray(b"Hello")

mv = memoryview(arr)

mv[0] = 74

print(arr) # bytearray(b'Jello')

こういうときに便利
メモリビューオブジェクトを使うことで、メモリ上のデータを直接参照して操作することができます。これにより、データのコピーを省略してメモリやパフォーマンスを節約することができます。
例えば、画像や音声などのバイナリデータを扱う場合、メモリビューオブジェクトを使ってデータの一部を切り出したり、変換したりすることができます。以下のコードは、Pillowという画像処理ライブラリを使って、画像ファイルをメモリビューオブジェクトに変換し、その一部を別の画像に貼り付ける例です。

from PIL import Image

 

# 画像ファイルを読み込む

img1 = Image.open('cat.jpg')

img2 = Image.open('dog.jpg')

 

# 画像をメモリビューオブジェクトに変換する

mv1 = memoryview(img1.tobytes())

mv2 = memoryview(img2.tobytes())

 

# メモリビューオブジェクトの一部を切り出す

mv1_part = mv1[:100000] # cat.jpgの最初の10万バイト

mv2_part = mv2[100000:200000] # dog.jpgの10万バイト目から20万バイト目

 

# メモリビューオブジェクトの一部を入れ替える

mv1[:100000] = mv2_part

mv2[100000:200000] = mv1_part

 

# メモリビューオブジェクトを画像に戻す

img1_new = Image.frombytes(img1.mode, img1.size, mv1)

img2_new = Image.frombytes(img2.mode, img2.size, mv2)

 

# 画像を保存する

img1_new.save('cat_new.jpg')

img2_new.save('dog_new.jpg')

このように、メモリビューオブジェクトを使うと、画像の一部を簡単に入れ替えることができます。もちろん、他のデータ形式や操作にも応用できます。メモリビューオブジェクトは、メモリ上のデータを効率的に扱うための便利な関数です。

(46)min()

引数(イテラブルオブジェクト)の中で最小の要素を返します。

arr = [1, 2, 3, 4, 5]

print(min(arr)) # 1

 

str = "Hello"

print(min(str)) # H

  • 注意点
    引数が空の場合にはValueErrorを発生させます。

arr =

print(min(arr)) # ValueError: min() arg is an empty sequence

この関数を知らないと…
イテラブルオブジェクトの中で最小の要素を探す際に、for文やif文を使った冗長なコードを書いてしまいます。

arr = [1, 2, 3, 4, 5]

min = arr[0]

for x in arr:

    if x < min:

        min = x

print(min) # 1

min関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 5]

print(min(arr)) # 1

(47)next()

引数(イテレータ)の次の要素を返します。

arr = [1, 2, 3, 4, 5]

it = iter(arr)

print(next(it)) # 1

print(next(it)) # 2

print(next(it)) # 3

  • 注意点
    引数がイテレータでない場合にはTypeErrorを発生させます。

arr = [1, 2, 3, 4, 5]

print(next(arr)) # TypeError: 'list' object is not an iterator

イテレータの要素がなくなった場合にはStopIterationを発生させます。

arr = [1, 2, 3, 4, 5]

it = iter(arr)

for i in range(6):

    print(next(it)) # 1, 2, 3, 4, 5, StopIteration

この関数を知らないと…
イテレータから要素を取り出す際に、for文を使わなければなりません。しかし、for文はイテレータの全要素を回すので、特定の要素だけを取り出したい場合には不便です。その場合、next関数を使って要素を取り出すことができます。

arr = [1, 2, 3, 4, 5]

it = iter(arr)

for x in it:

    print(x) # 1, 2, 3, 4, 5

next関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 5]

it = iter(arr)

print(next(it)) # 1

print(next(it)) # 2

print(next(it)) # 3

(48)object()

新しいオブジェクトを作成します。objectはPythonのすべてのクラスの基底クラスです。

obj = object()

print(obj) # <object object at 0x000001E8F1A6B9A0>

print(type(obj)) # <class 'object'>

  • 注意点
    objectクラスは属性やメソッドを持たないので、オブジェクトに対して操作を行うことはできません。

obj = object()

obj.x = 1 # AttributeError: 'object' object has no attribute 'x'

obj.__str__() # AttributeError: 'object' object has no attribute '__str__'

この関数を知らないと…
自分でクラスを定義するときに、objectクラスを継承しないと、Python 2では新スタイルクラスと古いスタイルクラスの違いによって予期しない動作を引き起こす可能性があります。なお、Python 3では、すべてのクラスが暗黙的にobjectクラスを継承するので、この問題はありません。

# Python 2

class A: # 古いスタイルクラス

    pass

 

class B(object): # 新スタイルクラス

    pass

 

print type(A) # <type 'classobj'>

print type(B) # <type 'type'>

object関数を使うと、以下のように書くことができます。

# Python 2

class A(object): # 新スタイルクラス

    pass

 

class B(object): # 新スタイルクラス

    pass

 

print type(A) # <type 'type'>

print type(B) # <type 'type'>

(49)oct()

引数(整数)を8進数の文字列に変換して返します。

num = 10

print(oct(num)) # 0o12

 

num = -10

print(oct(num)) # -0o12

  • 注意点
    引数が整数でない場合にはTypeErrorを発生させます。

num = 3.14

print(oct(num)) # TypeError: 'float' object cannot be interpreted as an integer

こういうときに便利

  • 8進数で表されたデータを扱うとき、oct関数を使うと、10進数から8進数に簡単に変換できます。

# ファイルのパーミッションを8進数で表示する

import os

file = "test.txt"

mode = os.stat(file).st_mode # 10進数でパーミッションを取得

print(Oct(mode)) # 8進数に変換して表示

# 100644

  • 2進数や16進数との相互変換をするとき。8進数は、2進数の3桁ごとに1桁になるので、2進数との変換が容易です。また、16進数は、8進数の2桁ごとに1桁になるので、16進数との変換も容易です。oct関数を使うと、10進数から8進数に変換できるので、2進数や16進数との相互変換に便利です。

# 2進数と8進数の相互変換

bin = "10101010" # 2進数

dec = int(bin, 2) # 10進数に変換

oct = Oct(dec) # 8進数に変換

print(bin, oct) # 2進数と8進数を表示

# 10101010 252

 

oct = "252" # 8進数

dec = int(oct, 8) # 10進数に変換

bin = bin(dec) # 2進数に変換

print(oct, bin) # 8進数と2進数を表示

# 252 0b10101010

# 16進数と8進数の相互変換

hex = "FF" # 16進数

dec = int(hex, 16) # 10進数に変換

oct = Oct(dec) # 8進数に変換

print(hex, oct) # 16進数と8進数を表示

# FF 377

 

oct = "377" # 8進数

dec = int(oct, 8) # 10進数に変換

hex = hex(dec) # 16進数に変換

print(oct, hex) # 8進数と16進数を表示

# 377 0xff

(50)open()

引数(ファイル名)を開いてファイルオブジェクトを返します。オプションでモードやエンコーディングなどを指定することができます。

f = open("test.txt", "w", encoding="utf-8")

f.write("Hello, world!")

f.close()

  • 注意点
    ファイルを開く際には、必ずcloseメソッドを呼び出してファイルを閉じる必要があります。そうしないと、ファイルに対する変更が保存されなかったり、他のプログラムからファイルにアクセスできなかったりする可能性があります。

f = open("test.txt", "w", encoding="utf-8")

f.write("Hello, world!")

# f.close() # 忘れてしまった

with文を使うと、ファイルを自動的に閉じることができます。

with open("test.txt", "w", encoding="utf-8") as f:

    f.write("Hello, world!")

# ファイルが自動的に閉じられる

この関数を知らないと…
ファイルを操作する際に、不要なモジュールのインポートが発生します。

import os

os.system("echo Hello, world! > test.txt")

open関数を使うと以下のように書くことができます。

f = open("test.txt", "w", encoding="utf-8")

f.write("Hello, world!")

f.close()

(51)ord()

引数(一文字の文字列)のUnicodeコードポイントを整数として返します。

char = "A"

print(ord(char)) # 65

 

char = "あ"

print(ord(char)) # 12354

  • 注意点
    引数が一文字の文字列でない場合にはTypeErrorを発生させます。

char = "AB"

print(ord(char)) # TypeError: ord() expected a character, but string of length 2 found

この関数を知らないと…
文字のUnicodeコードポイントを取得する際に、encodeメソッドやint関数を使った冗長なコードを書いてしまいます。

char = "A"

print(int.from_bytes(char.encode("utf-8"), "big")) # 65

ord関数を使うと以下のように書くことができます。

char = "A"

print(ord(char)) # 65

(52)pow()

第一引数(数値)を第二引数(数値)乗した結果を返します。オプションで第三引数(数値)を指定すると、その数値で割った余りを返します。

x = 2

y = 3

print(pow(x, y)) # 8

 

x = 2

y = 3

z = 5

print(pow(x, y, z)) # 3

  • 注意点
    第三引数が指定された場合には、第一引数と第二引数は整数でなければなりません。そうでない場合にはTypeErrorを発生させます。

x = 2.0

y = 3

z = 5

print(pow(x, y, z)) # TypeError: pow() 3rd argument not allowed unless all arguments are integers

こういうときに便利
この関数は、べき乗や剰余の計算をするときに便利です。例えば、暗号化や復号化のアルゴリズムによく使われます。RSA暗号やエルガマル暗号などの公開鍵暗号では、pow関数を使って秘密鍵や公開鍵を生成したり、メッセージを暗号化、復号化します。pow関数は、**演算子よりも高速に計算できるので、大きな数を扱うときに有効です。

(53)print()

引数(任意のオブジェクト)を標準出力に表示します。オプションで区切り文字や改行文字などを指定することができます。

print("Hello, world!") # Hello, world!

 

x = 1

y = 2

print(x, y) # 1 2

 

x = 1

y = 2

print(x, y, sep=", ") # 1, 2

 

x = 1

y = 2

print(x, y, end="\n\n") # 1 2

 

  • 注意点
    引数がない場合には、空白の行を出力します。

print() #

この関数を知らないと…
オブジェクトを標準出力に表示する際に、sysモジュールやstrメソッドを使った冗長なコードを書いてしまいます。

import sys

x = 1

y = 2

sys.stdout.write(str(x) + " " + str(y) + "\n") # 1 2

print関数を使うと以下のように書くことができます。

x = 1

y = 2

print(x, y) # 1 2

(54)property()

引数(ゲッター関数、セッター関数、デリーター関数、ドキュメント文字列)からプロパティオブジェクトを作成します。プロパティオブジェクトは、クラスの属性に対してゲッター、セッター、デリーター、ドキュメンテーションの動作を定義することができます。

class Person:

    def __init__(self, name):

        self._name = name

 

    def get_name(self):

        return self._name

 

    def set_name(self, value):

        self._name = value

 

    def del_name(self):

        del self._name

 

    name = property(get_name, set_name, del_name, "name property")

 

p = Person("Alice")

print(p.name) # Alice

p.name = "Bob"

print(p.name) # Bob

del p.name

print(p.name) # AttributeError: 'Person' object has no attribute '_name'

  • 注意点
    引数はすべてオプションですが、少なくともゲッター関数かセッター関数のどちらかは指定する必要があります。そうでない場合にはTypeErrorを発生させます。

class Person:

    def __init__(self, name):

        self._name = name

 

    name = property() # TypeError: property expected at least 1 argument, got 0

 

p = Person("Alice")

この関数を知らないと…
クラスの属性に対して、直接アクセスや変更を許可してしまうと、不正な値や予期せぬエラーが発生する可能性があります。また、属性の値を取得や設定するために、わざわざメソッドを呼び出す必要があります。property関数を使うと、属性のアクセスを制御しつつ、メソッドを呼び出さずに属性のように扱うことができます。

(55)range()

引数(開始値、終了値、ステップ値)から範囲オブジェクトを作成します。範囲オブジェクトは、開始値から終了値までのステップ値ごとの整数のシーケンスを表します。

r = range(10)

print(r) # range(0, 10)

print(list(r)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

r = range(1, 10, 2)

print(r) # range(1, 10, 2)

print(list(r)) # [1, 3, 5, 7, 9]

  • 注意点
    引数はすべて整数でなければなりません。そうでない場合にはTypeErrorを発生させます。

r = range(1.0, 10.0, 0.5) # TypeError: 'float' object cannot be interpreted as an integer

範囲オブジェクトはイテラブルですが、イテレータではありません。そのため、next関数を使って次の要素を取得することはできません。

r = range(10)

print(next(r)) # TypeError: 'range' object is not an iterator

この関数を知らないと…
整数のシーケンスを作成する際に、リスト内包表記やfor文を使った冗長なコードを書いてしまいます。

r = [x for x in range(10)]

print(r) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

r =

for x in range(10):

    r.append(x)

print(r) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range関数を使うと以下のように書くことができます。

r = range(10)

print(r) # range(0, 10)

print(list(r)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

(56)repr()

引数(object)のオブジェクトを、Pythonが復元できる文字列に変換して返します。reprはrepresentationの略です。この関数は、デバッグやログ出力などに使われます。

x = [1, 2, 3]

y = "Hello, world!"

z = 3.14

print(repr(x)) # '[1, 2, 3]'

print(repr(y)) # "'Hello, world!'"

print(repr(z)) # '3.14'

  • 注意点
    repr関数は、可能であれば、eval関数で評価すると元のオブジェクトに戻るような文字列を返すべきと定義されています。eval関数は、引数の文字列をPythonの式として実行する関数です。

x = [1, 2, 3]

s = repr(x) # '[1, 2, 3]'

x2 = eval(s) # [1, 2, 3]

print(x == x2) # True

ただし、repr関数が必ずしもeval関数で復元できる文字列を返すとは限りません。例えば、組み込みのdatetimeモジュールのdateクラスのオブジェクトをrepr関数で変換すると、以下のようになります。

import datetime

d = datetime.date(2023, 4, 20)

print(repr(d)) # 'datetime.date(2023, 4, 20)'

この文字列は、eval関数で評価するとエラーになります。なぜなら、datetimeモジュールがインポートされていないと、datetime.dateという名前が認識されないからです。

s = repr(d) # 'datetime.date(2023, 4, 20)'

d2 = eval(s) # NameError: name 'datetime' is not defined

このように、repr関数が返す文字列は、オブジェクトの型や内容を表すものであって、必ずしもPythonの式として有効なものではありません。そのため、repr関数を使うときは、そのオブジェクトがどのような文字列表現になるかを確認することが重要です。

この関数を知らないと…
オブジェクトの内容や型を確認するときに、str関数やprint関数だけを使ってしまうと、オブジェクトの正確な表現がわからないことがあります。例えば、文字列オブジェクトをstr関数やprint関数で変換すると、クオーテーションマークが省略されます。

s = "Hello, world!"

print(str(s)) # Hello, world!

print(s) # Hello, world!

これでは、sが文字列オブジェクトであることがわかりにくいです。repr関数を使うと、クオーテーションマークが付いて、文字列オブジェクトであることが明確になります。

s = "Hello, world!"

print(repr(s)) # 'Hello, world!'

(57)reversed()

引数(シーケンスオブジェクト)の逆順のイテレータを返します。

arr = [1, 2, 3, 4, 5]

it = reversed(arr)

print(it) # <list_reverseiterator object at 0x000001E8F1A6B9A0>

print(list(it)) # [5, 4, 3, 2, 1]

 

str = "Hello"

it = reversed(str)

print(it) # <reversed object at 0x000001E8F1A6B9A0>

print("".join(it)) # olleH

  • 注意点
    引数がシーケンスオブジェクトでない場合にはTypeErrorを発生させます。

num = 12345

it = reversed(num) # TypeError: 'int' object is not reversible

この関数を知らないと…
シーケンスオブジェクトの逆順のイテレータを作成する際に、スライスやfor文を使うこととなり、可読性が低下します。

arr = [1, 2, 3, 4, 5]

it = iter(arr[::-1])

print(it) # <list_iterator object at 0x000001E8F1A6B9A0>

print(list(it)) # [5, 4, 3, 2, 1]

 

str = "Hello"

it = ""

for x in str:

    it = x + it

print(it) # olleH

reversed関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 5]

it = reversed(arr)

print(it) # <list_reverseiterator object at 0x000001E8F1A6B9A0>

print(list(it)) # [5, 4, 3, 2, 1]

 

str = "Hello"

it = reversed(str)

print(it) # <reversed object at 0x000001E8F1A6B9A0>

print("".join(it)) # olleH

(58)round()

第一引数(数値)を第二引数(整数)で指定した桁数に丸めた結果を返します。第二引数が指定されない場合には、整数に丸めます。

num = 3.14159

print(round(num)) # 3

 

num = 3.14159

digits = 2

print(round(num, digits)) # 3.14

  • 注意点
    第二引数が負の場合には、10のべき乗の位に丸めます。

num = 12345

digits = -2

print(round(num, digits)) # 12300

この関数を知らないと…
数値を四捨五入する際に、10のべき乗をかけたり割ったりして煩雑なコードを書いてしまいます。

num = 3.14159

assert int(num + 0.5) == 3

assert int(num * 100 + 0.5) / 100 == 3.14

round関数を使うと以下のように書くことができます。

num = 3.14159

assert round(num) == 3

assert round(num, 2) == 3.14

(59)set()

引数(イテラブルオブジェクト)から重複を除いた集合を作成します。

arr = [1, 2, 3, 4, 4, 5]

s = set(arr)

print(s) # {1, 2, 3, 4, 5}

  • 注意点
    集合は順序がないので、インデックスやスライスで要素にアクセスすることはできません。

s = {1, 2, 3, 4, 5}

print(s[0]) # TypeError: 'set' object is not subscriptable

この関数を知らないと…
リストやタプルなどのイテラブルオブジェクトから重複を除くために、ループやif文を使って複雑な処理をする必要があります。

arr = [1, 2, 3, 4, 4, 5]

result =

for x in arr:

    if x not in result:

        result.append(x)

print(result) # [1, 2, 3, 4, 5]

set関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 4, 5]

result = set(arr)

print(result) # {1, 2, 3, 4, 5}

(60)setattr()

オブジェクトに指定した名前の属性を設定します。属性が存在しない場合は新しく作成されます。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

p = Person("Alice", 20)

setattr(p, "gender", "female") # p.gender = "female" と同じ

print(p.gender) # female

  • 注意点
    属性名は文字列で指定する必要があります。変数や式では指定できません。

p = Person("Alice", 20)

attr = "gender"

setattr(p, attr, "female") # OK

setattr(p, "gen" + "der", "female") # OK

setattr(p, attr + 1, "female") # TypeError: can only concatenate str (not "int") to str

この関数を知らないと…
オブジェクトの属性を動的に設定することができません。属性名をハードコードする必要があります。

p = Person("Alice", 20)

p.gender = "female" # OK

p.attr = "female" # NG (attrという属性が作成される)

setattr関数を使うと以下のように書くことができます。

p = Person("Alice", 20)

attr = "gender"

setattr(p, attr, "female") # OK (p.gender = "female" と同じ)

(61)slice()

引数(シーケンス)を指定した範囲で切り出したスライスオブジェクトを返します。

s = "Hello, world!"

sl = slice(7, 12) # インデックス7から12(終端の前まで)の範囲を指定

print(s[sl]) # スライスオブジェクトをインデックスとして使用

# 出力: World

  • 注意点
    slice関数は、スライスオブジェクトを作成するだけで、シーケンスを切り出すわけではありません。切り出すには、スライスオブジェクトをシーケンスのインデックスとして使用する必要があります。

s = "Hello, world!"

sl = slice(7, 12)

print(sl) # スライスオブジェクトをそのまま出力

# 出力: slice(7, 12, None)

この関数を知らないと…
スライス操作を行う際に、コロンを使った記法を使わざるを得ません。しかし、コロンを使った記法は、スライスの範囲を動的に変更することができません。例えば、以下のようなコードはエラーになります。

s = "Hello, world!"

start = 7

end = 12

print(s[start:end]) # これは正常に動作する

# 出力: World

print(s[start:]) # これも正常に動作する

# 出力: world!

print(s[start::2]) # これも正常に動作する

# 出力: Wrd

print(s[start::end]) # これはエラーになる

# 出力: SyntaxError: invalid syntax

slice関数を使うと、以下のように書くことができます。

s = "Hello, world!"

start = 7

end = 12

sl1 = slice(start, end) # ステップなし

sl2 = slice(start, None) # 終端なし

sl3 = slice(start, None, 2) # 終端なし、ステップ2

sl4 = slice(start, None, end) # 終端なし、ステップend

print(s[sl1]) # これは正常に動作する

# 出力: World

print(s[sl2]) # これも正常に動作する

# 出力: world!

print(s[sl3]) # これも正常に動作する

# 出力: Wrd

print(s[sl4]) # これも正常に動作する

# 出力: W

slice関数は、スライス操作をより柔軟に行うための便利な関数です。スライスオブジェクトを作成して、シーケンスのインデックスとして使用することで、シーケンスの一部を切り出すことができます。

(62)sorted()

引数(イテラブルオブジェクト)の要素をソートした新しいリストを返します。

arr = [5, 2, 4, 1, 3]

result = sorted(arr)

print(result) # [1, 2, 3, 4, 5]

  • 注意点
    sorted関数は引数のオブジェクトを変更しません。新しいリストを作成して返します。引数のオブジェクトを変更するには、sortメソッドを使います。

arr = [5, 2, 4, 1, 3]

result = sorted(arr)

print(arr) # [5, 2, 4, 1, 3]

print(result) # [1, 2, 3, 4, 5]

arr.sort()

print(arr) # [1, 2, 3, 4, 5]

この関数を知らないと…
イテラブルオブジェクトの要素をソートするために、ループやif文を使って複雑な処理を行う必要があります。また、ソートした結果を別のリストに保存するために、コピーを作る必要があります。

arr = [5, 2, 4, 1, 3]

result = arr.copy()

for i in range(len(result)):

    for j in range(i + 1, len(result)):

        if result[i] > result[j]:

            result[i], result[j] = result[j], result[i]

print(arr) # [5, 2, 4, 1, 3]

print(result) # [1, 2, 3, 4, 5]

sorted関数を使うと以下のように書くことができます。

arr = [5, 2, 4, 1, 3]

result = sorted(arr)

print(arr) # [5, 2, 4, 1, 3]

print(result) # [1, 2, 3, 4, 5]

(63)staticmethod()

メソッドを静的メソッドに変換します。静的メソッドは、クラスやインスタンスに依存しないメソッドです。静的メソッドは、クラス名やインスタンスから呼び出すことができますが、第一引数にselfやclsを受け取りません。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

    @staticmethod

    def say_hello():

        print("Hello")

 

p = Person("Alice", 20)

Person.say_hello() # Hello

p.say_hello() # Hello

  • 注意点
    静的メソッドは、クラスの属性やメソッドにアクセスすることができません。クラスの属性やメソッドにアクセスするには、クラスメソッドを使います。

class Person:

    count = 0

 

    def __init__(self, name, age):

        self.name = name

        self.age = age

        Person.count += 1

 

    @staticmethod

    def get_count():

        return Person.count # クラス名を明示的に指定する必要がある

 

    @classmethod

    def get_count2(cls):

        return cls.count # clsを使ってクラスの属性にアクセスできる

 

p = Person("Alice", 20)

print(Person.get_count()) # 1

print(Person.get_count2()) # 1

この関数を知らないと…
クラスやインスタンスに関係なく共通の処理を行うメソッドを作ることができません。クラスやインスタンスの属性やメソッドを使わないメソッドを定義すると、不要なselfやclsを引数に受け取る必要があります。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

    def say_hello(self): # selfを引数に受け取る必要がある

        print("Hello")

 

p = Person("Alice", 20)

p.say_hello() # Hello

staticmethod関数を使うと以下のように書くことができます。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

    @staticmethod

    def say_hello(): # selfを引数に受け取らない

        print("Hello")

 

p = Person("Alice", 20)

p.say_hello() # Hello

(64)str()

引数(オブジェクト)を文字列に変換します。

num = 123

s = str(num)

print(s) # '123'

print(type(s)) # <class 'str'>

  • 注意点
    str関数は引数のオブジェクトの__str__メソッドを呼び出して文字列を返します。__str__メソッドはオブジェクトの「非公式な」文字列表現を返すメソッドです。__str__メソッドが定義されていない場合は、__repr__メソッドが呼び出されます。__repr__メソッドはオブジェクトの「公式な」文字列表現を返すメソッドです。

class Person:

    def __init__(self, name, age):

        self.name = name

        self.age = age

 

    def __str__(self):

        return f"{self.name} is {self.age} years old."

 

    def __repr__(self):

        return f"Person(name='{self.name}', age={self.age})"

 

p = Person("Alice", 20)

print(str(p)) # Alice is 20 years old.

print(repr(p)) # Person(name='Alice', age=20)

この関数を知らないと…
オブジェクトを文字列に変換することができません。文字列として扱いたい場合に、エラーが発生する可能性があります。

num = 123

print("The number is " + num) # TypeError: can only concatenate str (not "int") to str

str関数を使うと以下のように書くことができます。

num = 123

print("The number is " + str(num)) # The number is 123

(65)sum()

引数(イテラブルオブジェクト)の要素の合計を返します。オプションで、第二引数に初期値を指定できます。

arr = [1, 2, 3, 4, 5]

result = sum(arr)

print(result) # 15

result = sum(arr, 10) # 初期値を10に指定

print(result) # 25

  • 注意点
    引数の要素は数値でなければなりません。文字列や他の型の要素を含む場合は、エラーが発生します。

arr = [1, 2, "3", 4, 5]

result = sum(arr) # TypeError: unsupported operand type(s) for +: 'int' and 'str'

この関数を知らないと…
イテラブルオブジェクトの要素の合計を求めるために、ループや変数を使って冗長なコードを書くことになります。

arr = [1, 2, 3, 4, 5]

result = 0

for x in arr:

    result += x

print(result) # 15

sum関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 5]

result = sum(arr)

print(result) # 15

(66)super()

親クラスのオブジェクトを返します。親クラスのオブジェクトは、サブクラスのオブジェクトから親クラスの属性やメソッドにアクセスするために使われます。

class Animal:

    def __init__(self, name):

        self.name = name

 

    def sound(self):

        print("...")

 

class Dog(Animal):

    def __init__(self, name, breed):

        super().__init__(name) # 親クラスの__init__メソッドを呼び出す

        self.breed = breed

 

    def sound(self):

        super().sound() # 親クラスのsoundメソッドを呼び出す

        print("Woof")

 

d = Dog("Spot", "Labrador")

d.sound() # ... Woof

  • 注意点
    super関数は、クラスの継承関係に基づいて親クラスのオブジェクトを返します。引数にクラスやインスタンスを指定することもできますが、通常は引数なしで使われます。

class Animal:

    def __init__(self, name):

        self.name = name

 

    def sound(self):

        print("...")

 

class Dog(Animal):

    def __init__(self, name, breed):

        Animal.__init__(self, name) # 親クラスの__init__メソッドを直接呼び出す

        self.breed = breed

 

    def sound(self):

        Animal.sound(self) # 親クラスのsoundメソッドを直接呼び出す

        print("Woof")

 

d = Dog("Spot", "Labrador")

d.sound() # ... Woof

この関数を知らないと…
サブクラスのオブジェクトから親クラスの属性やメソッドにアクセスすることができません。親クラスの名前やインスタンスを明示的に指定する必要があります。

class Animal:

    def __init__(self, name):

        self.name = name

 

    def sound(self):

        print("...")

 

class Dog(Animal):

    def __init__(self, name, breed):

        self.name = name # 親クラスの属性を直接設定する

        self.breed = breed

 

    def sound(self):

        print("...") # 親クラスのメソッドをコピーする

        print("Woof")

 

d = Dog("Spot", "Labrador")

d.sound() # ... Woof

super関数を使うと以下のように書くことができます。

class Animal:

    def __init__(self, name):

        self.name = name

 

    def sound(self):

        print("...")

 

class Dog(Animal):

    def __init__(self, name, breed):

        super().__init__(name) # 親クラスの__init__メソッドを呼び出す

        self.breed = breed

 

    def sound(self):

        super().sound() # 親クラスのsoundメソッドを呼び出す

        print("Woof")

 

d = Dog("Spot", "Labrador")

d.sound() # ... Woof

(67)tuple()

引数(イテラブルオブジェクト)からタプルを作成します。タプルは、変更できない順序付きのコレクションです。

arr = [1, 2, 3, 4, 5]

t = tuple(arr)

print(t) # (1, 2, 3, 4, 5)

print(type(t)) # <class 'tuple'>

  • 注意点
    タプルは変更できないので、要素の追加や削除、変更などの操作はできません。

t = (1, 2, 3, 4, 5)

t[0] = 10 # TypeError: 'tuple' object does not support item assignment

t.append(6) # AttributeError: 'tuple' object has no attribute 'append'

t.remove(5) # AttributeError: 'tuple' object has no attribute 'remove'

この関数を知らないと…
イテラブルオブジェクトからタプルを作ることができません。タプルとして扱いたい場合に、エラーが発生する可能性があります。

arr = [1, 2, 3, 4, 5]

print(arr + (6, 7)) # TypeError: can only concatenate list (not "tuple") to list

tuple関数を使うと以下のように書くことができます。

arr = [1, 2, 3, 4, 5]

t = tuple(arr)

print(t + (6, 7)) # (1, 2, 3, 4, 5, 6, 7)

(68)type()

引数(オブジェクト)の型を返します。型とは、オブジェクトの種類や特徴を表すものです。

num = 123

s = "Hello"

t = (1, 2, 3)

print(type(num)) # <class 'int'>

print(type(s)) # <class 'str'>

print(type(t)) # <class 'tuple'>

  • 注意点
    type関数は、引数が一つの場合は型を返しますが、引数が三つの場合は新しい型を作成します。引数が三つの場合は、第一引数に型の名前、第二引数に基底クラスのタプル、第三引数に属性やメソッドの辞書を指定します。

# 引数が一つの場合

num = 123

print(type(num)) # <class 'int'>

 

# 引数が三つの場合

Person = type("Person", (object,), {"name": "Alice", "age": 20, "say_hello": lambda self: print(f"Hello, I'm {self.name}.")})

p = Person()

print(type(p)) # <class '__main__.Person'>

print(p.name) # Alice

print(p.age) # 20

p.say_hello() # Hello, I'm Alice.

この関数を知らないと…
オブジェクトの型を調べることができません。型によってオブジェクトの振る舞いや操作が異なるので、エラーが発生する可能性があります。

num = 123

s = "Hello"

print(num + s) # TypeError: unsupported operand type(s) for +: 'int' and 'str'

type関数を使うと以下のように書くことができます。

num = 123

s = "Hello"

print(type(num)) # <class 'int'>

print(type(s)) # <class 'str'>

print(str(num) + s) # 123Hello

(69)vars()

引数に指定したオブジェクトの属性と値の辞書を返します。引数を省略した場合は、現在のローカルシンボルテーブルを返します。

class Sample:

    def __init__(self, x, y):

        self.x = x

        self.y = y

 

s = Sample(1, 2)

print(vars(s)) # {'x': 1, 'y': 2}

 

print(vars()) # 現在のローカルシンボルテーブルを表示

  • 注意点
    vars()はモジュール、クラス、インスタンスなどの属性を持つオブジェクトに対して有効ですが、数値や文字列などの属性を持たないオブジェクトに対してはTypeErrorを発生させます。

print(vars(1)) # TypeError: vars() argument must have __dict__ attribute

この関数は、オブジェクトの内部状態を調べたり、動的に属性を追加したりするときに便利です。

class Sample:

    def __init__(self, x, y):

        self.x = x

        self.y = y

 

obj = Sample(1, 2)

print(vars(obj))

# {'x': 1, 'y': 2}

 

# 動的に属性を追加

vars(obj)['z'] = 3

print(vars(obj))

# {'x': 1, 'y': 2, 'z': 3}

 

# オブジェクトの属性を辞書として扱える

for key, value in vars(obj).items():

    print(f"{key} = {value}")

# x = 1

# y = 2

# z = 3

このように、vars関数を使うと、オブジェクトの属性を辞書として扱うことができます。これは、オブジェクト指向プログラミングの柔軟性を高めるのに役立ちます。

(70)zip()

複数のイテラブルオブジェクトを引数にとり、それらの要素をまとめたイテレータを返します。イテレータの要素は、引数のイテラブルオブジェクトの要素を対応させたタプルになります。

a = [1, 2, 3]

b = ['a', 'b', 'c']

c = zip(a, b) # イテレータを返す

print(list(c)) # [(1, 'a'), (2, 'b'), (3, 'c')]

  • 注意点
    引数のイテラブルオブジェクトの長さが異なる場合、zip()は最も短いイテラブルオブジェクトが終了するまで要素をまとめます。残りの要素は無視されます。

a = [1, 2, 3, 4]

b = ['a', 'b', 'c']

c = zip(a, b) # イテレータを返す

print(list(c)) # [(1, 'a'), (2, 'b'), (3, 'c')]

この関数を知らないと…
複数のイテラブルオブジェクトの要素をまとめるためには、for文やリスト内包表記などを使って実装する必要がありますが、これはコードが冗長になります。

a = [1, 2, 3]

b = ['a', 'b', 'c']

c = []

for i in range(min(len(a), len(b))):

    c.append*1

print(c) # [(1, 'a'), (2, 'b'), (3, 'c')]

zip関数を使うと以下のように書くことができます。

a = [1, 2, 3]

b = ['a', 'b', 'c']

c = zip(a, b) # イテレータを返す

print(list(c)) # [(1, 'a'), (2, 'b'), (3, 'c')]

(71)__import__()

引数に指定したモジュール名の文字列に対応するモジュールをインポートします。戻り値はインポートされたモジュールオブジェクトです。

math = __import__('math') # mathモジュールをインポート

print(math.pi) # 3.141592653589793

  • 注意点
    __import__()は低レベルな関数であり、通常はimport文を使ってモジュールをインポートすることが推奨されます。__import__()は主にモジュール名が動的に決まる場合や、カスタマイズされたインポート機構を実装する場合に使われます。

module_name = input('Enter a module name: ') # モジュール名を入力

module = __import__(module_name) # 入力されたモジュールをインポート

この関数を知らないと…
モジュール名が文字列として与えられた場合、import文ではモジュールをインポートすることができません。代わりに、importlibモジュールのimport_module関数を使うことができますが、これは内部的に__import__()を呼び出しています。

import importlib

math = importlib.import_module('math') # mathモジュールをインポート

print(math.pi) # 3.141592653589793

__import__()関数を使うと以下のように書くことができます。

math = __import__('math') # mathモジュールをインポート

print(math.pi) # 3.141592653589793

おわりに

最後までお読みいただきありがとうございます。

各関数の機能や注意点、使いどころを理解することで、Pythonのコードをより効率的に、簡潔に、美しく書くことができます。
Pythonは、データ分析や機械学習、ウェブ開発やゲーム開発など、様々な分野で活躍できるプログラミング言語です。Pythonの組み込み関数を使いこなすことは、Pythonの基礎を固めることにつながります。Pythonの組み込み関数を使って、素敵なコードを書いてください。それでは、また。

弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています!興味をお持ちいただける方は、こちらまで。

(Qiitaより転載)

人気ブログランキングへ←人気ブログランキングに参加しています。ポチっと1票を!

*1:a[i], b[i]

240101能登半島地震

240101能登半島地震

今回の地震で被害にあった人たちに対してお見舞い申し上げます。っ正月気分もすっ飛んでしまいました。

令和6年おせち料理

今年も正月料理は手抜き料理で済ませました。

人気ブログランキングへ←人気ブログランキングに参加しています。ポチっと1票を!