Pythonで辞書とタプルを使用する場合


31

特定の例は、ファイル名とそのサイズのリストです。リストの各アイテムがフォーム{"filename": "blabla", "size": 123}であるべきか、それともただであるべきであるか決定できません("blabla", 123)。たとえば、サイズにアクセスすることfile["size"]は、file[1]... よりも説明が多いため、辞書は私にとってより論理的なように思えますが、確かにわかりません。考え?


補足として、タプルの読みやすさを心配している場合、タプルのアンパックを検討してください- fname, file_size = fileデータがあなたの上のタプルである場合、file[1]それを廃止して置き換えfile_sizeます。もちろん、これは優れたドキュメントに依存しています。
nlsdfnbch

2
それは、どのデータ構造を構築しているか、そしてどのようにアクセスするつもりかによって異なります。(ファイル名で?インデックスで?両方?)それは単なる使い捨ての変数/データ構造ですか、それとも他のアイテム(/属性)とサイズを追加するのでしょうか?構造は順序を記憶する必要がありますか?サイズのリストをソートしますか、それとも位置でアクセスしますか(例:「上位n個の最大/最小ファイル」)。それらに応じて、「最良の」答えは、dict、OrderedDict、namedtuple、プレーンオールドリスト、または独自のカスタムクラスです。あなたからより多くのコンテキストが必要です。
SMCI

回答:


78

私は使用しnamedtupleます:

from collections import namedtuple
Filesize = namedtuple('Filesize', 'filename size')
file = Filesize(filename="blabla", size=123)

今、あなたは使用することができますfile.sizeし、file.filename私見最も読みやすい形式で、プログラム、インチ Note namedtupleはタプルのような不変オブジェクトを作成し、ここで説明するように、辞書よりも軽量です


1
ありがとう、良いアイデア、今日まで彼らのことを聞いたことがない(私はPythonでかなり初心者です)。質問:コード内の他の誰かが同じ「クラス」を定義している場合、おそらくわずかに異なる場合はどうなりますか。たとえば、他のソースファイルでは、同僚のボブがFilesize = namedtuple('Filesize', 'filepath kilobytes')
user949300

また、非常に優れたattrsモジュールを使用して(pip検索または検索のみ)、名前付きタプルと非常によく似た構文上の利便性を実現できますが、可変性を提供できます(ただし、不変にすることもできます)。主な機能的な違いは、attrs-madeクラスはnamedtuples のように普通のタプルと同等ではないことです。
mtraceur

3
@DocBrown Pythonには宣言の概念はありません。classdef、および=すべてのただの以前の使用を上書きします。repl.it-
チャレンジャー5

@ Challenger5:あなたは正しい、私の間違いなので、正しい答えは:最新の定義カウント、Pythonランタイムからのエラーはありませんが、他の変数と同様の動作です。
ドックブラウン

8
これnamedtupleは、本質的に、不変の属性を持つ新しい型の簡易宣言であることに注意してください。これは、「どちらも、答えは効果的であることを意味しtupleたりdict、けどobject。」+1
jpmc26

18

{「ファイル名」:「blabla」、「サイズ」:123}、または単に(「blabla」、123)

これは、フォーマット/スキーマを帯域内でエンコードするか帯域外でエンコードするかという古くからの質問です。

データの形式をデータで直接表現することで得られる読みやすさと移植性を得るために、いくらかのメモリをトレードオフします。これを行わない場合、最初のフィールドはファイル名であり、2番目のフィールドはサイズであるという知識は、他の場所に保持する必要があります。これはメモリを節約しますが、読みやすさと移植性が犠牲になります。あなたの会社により多くのお金がかかるのはどれですか?

不変の問題に関しては、不変は変化に直面しても役に立たないという意味ではないことを忘れないでください。つまり、より多くのメモリを取得し、コピーに変更を加え、新しいコピーを使用する必要があります。それは無料ではありませんが、多くの場合、契約違反ではありません。常に変更を加えるために不変の文字列を使用しています。

もう1つの考慮事項は拡張性です。フォーマット情報をエンコードせずに位置のみでデータを保存すると、単一の継承のみに非難されます。これは実際には、確立されたフィールドの後に追加フィールドを連結する方法に他なりません。最初と2番目のフィールドを同じように定義するので、3番目のフィールドを作成日として定義しても、フォーマットと互換性があります。

しかし、私ができないことは、いくつかの重複するフィールドを持ついくつかの独立して定義されたフォーマットを集め、いくつかのフィールドをそれらを1つのフォーマットに保存し、1つまたは他のフォーマットのみを知っているものに役立つことです。

そのためには、最初からフォーマット情報をエンコードする必要があります。「このフィールドはファイル名です」と言う必要があります。これにより、多重継承が可能になります。

おそらくオブジェクトのコンテキストでのみ表現される継承に慣れていますが、オブジェクトはデータ形式で保存されているため、データ形式でも同じ考えが機能します。それはまったく同じ問題です。

そのため、必要と思われる方を使用してください。正当な理由を指摘できない限り、柔軟性を確保します。


3
正直に言うと、私は疑う使用して間が不明だ誰インバンドまたはアウトオブバンド形式彼らは、アウトオブバンドの形式を使用する必要性に必要であろうと、このような厳しい性能要件がある
アレクサンダー-復活モニカ

2
@アレクサンダーは非常に本当です。帯域外ソリューションに直面したときに彼らが見ているものを理解するように、私はそれについて人々に教えることを好む。多くの場合、バイナリ形式は難読化のためにこれを行います。誰もがポータブルになりたいわけではありません。パフォーマンス上の理由として、本当に重要な場合は、帯域外に頼る前に圧縮を検討してください。
candied_orange

OPはPythonを使用していることを忘れないでください。したがって、おそらくパフォーマンスについてはあまり心配していません。ほとんどの高レベルコードは、最初に読みやすさを考慮して記述する必要があります。早すぎる最適化はすべての悪の根源です。
ダグルームズ

@DagroomsはPythonを嫌っていません。多くの場合、うまく機能します。しかし、そうでなければ、あなたが言ったことすべてに同意します。私のポイントは、「これが人々がそうする理由です。ここにあなたが気にしない可能性がある理由があります」と言いました。
-candied_orange

@CandiedOrange私は言語が嫌いではない、私は私の仕事でそれを使用しています。私は人々がそれを使用する方法が嫌いです。
ダグルームズ

7

2つのプロパティを持つクラスを使用します。file.sizeは、file[1]またはのいずれよりも優れていますfile["size"]

単純なものは複雑なものよりも優れています。


同様に良好に、作業の両方をJSONsを生成する:場合に誰かが思っているfile = Filesize(filename='stuff.txt', size=222)filetup = ("stuff.txt", 222)同じJSONを生成両方:json.dumps(file)json.dumps(filetup)をもたらす:'["stuff.txt", 222]'
ユハUntinen

5

ファイル名は一意ですか?その場合、リスト全体を廃棄し、すべてのファイルに純粋な辞書を使用するだけで済みます。例(架空のWebサイト)

{ 
  "/index.html" : 5467,
  "/about.html" : 3425,
  "/css/main.css" : 9876
}

等...

現在、「名前」と「サイズ」は取得せず、キーと値を使用するだけですが、多くの場合これはより自然です。YMMV。

明確にするために「サイズ」が本当に必要な場合、またはファイルに複数の値が必要な場合は、次のようにします。

{ 
   "/index.html" : { "size": 5467, "mime_type" : "foo" },
   "/about.html" : { "size": 3425, "mime_type" : "foo" }
   "/css/main.css" : { "size": 9876, "mime_type" : "bar" }
}

0

Pythonでは、辞書は可変オブジェクトです。反対に、タプルは不変オブジェクトです。

辞書キー、値のペアを頻繁に、または毎回変更する必要がある場合。使用する辞書を提案します。

固定/静的データがある場合は、タプルを使用することをお勧めします。

# dictionary define.
a = {}
a['test'] = 'first value'

# tuple define.
b = ()
b = b+(1,)

# here, we can change dictionary value for key 'test'
a['test'] = 'second'

ただし、代入演算子を使用してタプルデータを変更することはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.