48

既存の「最も有用なC/C ++スニペットは何ですか」の精神で-スレッド:

使用している(多くの場合)、StackOverlowコミュニティと共有したい短い単機能のPythonスニペットがありますか?エントリを小さく(25行未満でしょうか?)、投稿ごとに1つの例のみを示してください。

Pythonプロジェクトでsloc(コードのソース行)をカウントするために時々使用する短いスニペットから始めます。

# prints recursive count of lines of python source code from current directory
# includes an ignore_list. also prints total sloc

import os
cur_path = os.getcwd()
ignore_set = set(["__init__.py", "count_sourcelines.py"])

loclist = []

for pydir, _, pyfiles in os.walk(cur_path):
    for pyfile in pyfiles:
        if pyfile.endswith(".py") and pyfile not in ignore_set:
            totalpath = os.path.join(pydir, pyfile)
            loclist.append( ( len(open(totalpath, "r").read().splitlines()),
                               totalpath.split(cur_path)[1]) )

for linenumbercount, filename in loclist: 
    print "%05d lines in %s" % (linenumbercount, filename)

print "\nTotal: %s lines (%s)" %(sum([x[0] for x in loclist]), cur_path)
4

22 に答える 22

37

any私はジェネレーターを使用するのが好きです:

if any(pred(x.item) for x in sequence):
    ...

次のように記述されたコードの代わりに:

found = False
for x in sequence:
    if pred(x.n):
        found = True
if found:
    ...

私がこの手法を最初に知ったのは、Peter Norvig の記事です。

于 2009-03-29T05:57:20.420 に答える
23

2D リストの初期化

これはリストを初期化するために安全に実行できますが、次のようになります。

lst = [0] * 3

同じトリックは、2D リスト (リストのリスト) では機能しません。

>>> lst_2d = [[0] * 3] * 3
>>> lst_2d
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> lst_2d[0][0] = 5
>>> lst_2d
[[5, 0, 0], [5, 0, 0], [5, 0, 0]]

演算子 * はそのオペランドを複製し、[] で構築された複製リストは同じリストを指します。これを行う正しい方法は次のとおりです。

>>> lst_2d = [[0] * 3 for i in xrange(3)]
>>> lst_2d
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> lst_2d[0][0] = 5
>>> lst_2d
[[5, 0, 0], [0, 0, 0], [0, 0, 0]]
于 2009-03-28T08:35:01.780 に答える
22

私が知っている唯一の「トリック」は、それを知ったときに本当に驚きました。for ループ内の要素のインデックスにアクセスできます。

>>> l = ['a','b','c','d','e','f']
>>> for (index,value) in enumerate(l):
...     print index, value
... 
0 a
1 b
2 c
3 d
4 e
5 f
于 2009-03-28T02:16:45.340 に答える
18

zip(*iterable)イテラブルを転置します。

>>> a=[[1,2,3],[4,5,6]]
>>> zip(*a)
    [(1, 4), (2, 5), (3, 6)]

辞書にも役立ちます。

>>> d={"a":1,"b":2,"c":3}
>>> zip(*d.iteritems())
[('a', 'c', 'b'), (1, 3, 2)]
于 2009-03-28T18:11:56.060 に答える
16

現在のディレクトリ内のファイルに対して単純なWebサーバーを起動します。

python -m SimpleHTTPServer

ファイルの共有に便利です。

于 2011-09-16T15:40:14.590 に答える
14

次のような「進行状況バー」:

|#############################---------------------|
59 percent done

コード:

class ProgressBar():
    def __init__(self, width=50):
        self.pointer = 0
        self.width = width

    def __call__(self,x):
         # x in percent
         self.pointer = int(self.width*(x/100.0))
         return "|" + "#"*self.pointer + "-"*(self.width-self.pointer)+\
                "|\n %d percent done" % int(x) 

テスト機能 (Windows システムの場合、「クリア」を「CLS」に変更):

if __name__ == '__main__':
    import time, os
    pb = ProgressBar()
    for i in range(101):
        os.system('clear')
        print pb(i)
        time.sleep(0.1)
于 2010-12-13T16:27:04.580 に答える
11

次のようなリストのリストをフラット化するには

[['a', 'b'], ['c'], ['d', 'e', 'f']]

の中へ

['a', 'b', 'c', 'd', 'e', 'f']

使用する

[inner
    for outer in the_list
        for inner in outer]
于 2009-03-29T01:47:41.923 に答える
10

ネストされたリストと辞書の大幅な高速化:

deepcopy = lambda x: cPickle.loads(cPickle.dumps(x))
于 2009-03-28T21:36:56.050 に答える
8

アイテムのリストがあり、これらのアイテムをキーとして持つ辞書が必要だとします。fromkeys を使用します。

>>> items = ['a', 'b', 'c', 'd']
>>> idict = dict().fromkeys(items, 0)
>>> idict
{'a': 0, 'c': 0, 'b': 0, 'd': 0}
>>>

fromkeys の 2 番目の引数は、新しく作成されたすべてのキーに付与される値です。

于 2009-03-28T08:36:40.793 に答える
7

行が空かどうか (つまり、サイズが 0 であるか、空白のみが含まれているか) を調べるには、次のように、条件で string メソッド strip を使用します。

if not line.strip():    # if line is empty
    continue            # skip it
于 2009-03-28T08:35:49.173 に答える
5

私はこれがディレクトリ内のすべてを圧縮するのが好きです。instabackupsのためにそれをホットキー!

import zipfile

z = zipfile.ZipFile('my-archive.zip', 'w', zipfile.ZIP_DEFLATED)
startdir = "/home/johnf"
for dirpath, dirnames, filenames in os.walk(startdir):
  for filename in filenames:
    z.write(os.path.join(dirpath, filename))
z.close()
于 2009-03-28T01:13:34.323 に答える
5

最新のものが必要なリスト内包表記については、次を参照してください。

[fun(curr,next) 
 for curr,next 
 in zip(list,list[1:].append(None)) 
 if condition(curr,next)] 

循環リストの場合zip(list,list[1:].append(list[0]))

以前の場合、現在:zip([None].extend(list[:-1]),list)循環:zip([list[-1]].extend(list[:-1]),list)

于 2009-03-28T21:32:02.100 に答える
4

現在のディレクトリ内の同一のファイルをハードリンクします(UNIXでは、これは物理ストレージを共有していることを意味し、スペースがはるかに少ないことを意味します):

import os
import hashlib

dupes = {}

for path, dirs, files in os.walk(os.getcwd()):
    for file in files:
        filename = os.path.join(path, file)
        hash = hashlib.sha1(open(filename).read()).hexdigest()
        if hash in dupes:
            print 'linking "%s" -> "%s"' % (dupes[hash], filename)
            os.rename(filename, filename + '.bak')
            try:
                os.link(dupes[hash], filename)
                os.unlink(filename + '.bak')
            except:
                os.rename(filename + '.bak', filename)
            finally:
        else:
            dupes[hash] = filename
于 2009-03-28T01:10:48.713 に答える
3

知っておく価値があると思うが、日常的には役に立たないかもしれないものをいくつか紹介します。それらのほとんどはワンライナーです。

リストからの重複の削除

L = list(set(L))

文字列から整数を取得する(スペースで区切る)

ints = [int(x) for x in S.split()]

階乗を見つける

fac=lambda(n):reduce(int.__mul__,range(1,n+1),1)

最大公約数を見つける

>>> def gcd(a,b):
...     while(b):a,b=b,a%b
...     return a
于 2011-04-18T19:15:51.243 に答える
2
  • 上の別の人のように、私は「うわー!!」と言った。enumerate()を発見したとき

  • 正規表現で分析したい文字列の内容を正確に見ることができるrepr()を発見したとき、私は Python を称賛しました。

  • '\n'.join(...)よりもprint '\n'.join(list_of_strings)はるかに高速に表示されることを発見して、非常に満足しました。for ch in list_of_strings: print ch

  • 引数付きのsplitlines(1)は改行を保持します

これらの 4 つの「トリック」を 1 つのスニペットに組み合わせることで、Web ページのコード ソースを 1 行ずつすばやく表示するのに非常に便利です。現在:

import urllib
from time import clock,sleep

sock = urllib.urlopen('http://docs.python.org/')
ch = sock.read()
sock.close()


te = clock()
for i,line in enumerate(ch.splitlines(1)):
    print str(i) + ' ' + repr(line)
t1 = clock() - te


print "\n\nIn 3 seconds, I will print the same content, using '\\n'.join(....)\n" 

sleep(3)

te = clock()
# here's the point of interest:
print '\n'.join(str(i) + ' ' + repr(line)
                for i,line in enumerate(ch.splitlines(1)) )
t2 = clock() - te

print '\n'
print 'first  display took',t1,'seconds'
print 'second display took',t2,'seconds'

あまり高速ではないコンピューターで、次の結果が得られました。

first  display took 4.94626048841 seconds
second display took 0.109297410704 seconds
于 2011-04-17T16:41:15.717 に答える
2
import tempfile
import cPickle

class DiskFifo:
    """A disk based FIFO which can be iterated, appended and extended in an interleaved way"""
    def __init__(self):
        self.fd = tempfile.TemporaryFile()
        self.wpos = 0
        self.rpos = 0
        self.pickler = cPickle.Pickler(self.fd)
        self.unpickler = cPickle.Unpickler(self.fd)
        self.size = 0

    def __len__(self):
        return self.size

    def extend(self, sequence):
        map(self.append, sequence)

    def append(self, x):
        self.fd.seek(self.wpos)
        self.pickler.clear_memo()
        self.pickler.dump(x)
        self.wpos = self.fd.tell()
        self.size = self.size + 1

    def next(self):
        try:
            self.fd.seek(self.rpos)
            x = self.unpickler.load()
            self.rpos = self.fd.tell()
            return x

        except EOFError:
            raise StopIteration

    def __iter__(self):
        self.rpos = 0
        return self
于 2011-08-18T00:28:38.123 に答える
2

switch ステートメントをエミュレートします。たとえば、switch(x) {..}:

def a():
  print "a"

def b():
  print "b"

def default():
   print "default"

apply({1:a, 2:b}.get(x, default))
于 2011-04-17T14:38:13.270 に答える
1

For Python 2.4+ or earlier:

for x,y in someIterator:
  listDict.setdefault(x,[]).append(y)

In Python 2.5+ there is alternative using defaultdict.

于 2009-03-29T10:46:58.430 に答える
1

x要素のチャンクで、任意のサイズ(未知のサイズを含む)のイテラブル(リスト、セット、ファイル、ストリーム、文字列など)を反復処理します。

from itertools import chain, islice

def chunks(iterable, size, format=iter):
    it = iter(iterable)
    while True:
        yield format(chain((it.next(),), islice(it, size - 1)))

>>> l = ["a", "b", "c", "d", "e", "f", "g"]
>>> for chunk in chunks(l, 3, tuple):
...         print chunk
...     
("a", "b", "c")
("d", "e", "f")
("g",)
于 2012-08-07T08:30:43.127 に答える
1

他のリストと乗算するとデカルト積を返すカスタム リスト...良い点は、デカルト積がインデックス可能であり、 itertools.product とは異なります (ただし、被乗数はイテレータではなくシーケンスである必要があります)。

import operator

class mylist(list):
    def __getitem__(self, args):
        if type(args) is tuple:
            return [list.__getitem__(self, i) for i in args]
        else:
            return list.__getitem__(self, args)
    def __mul__(self, args):
        seqattrs = ("__getitem__", "__iter__", "__len__")
        if all(hasattr(args, i) for i in seqattrs):
            return cartesian_product(self, args)
        else:
            return list.__mul__(self, args)
    def __imul__(self, args):
        return __mul__(self, args)
    def __rmul__(self, args):
        return __mul__(args, self)
    def __pow__(self, n):
        return cartesian_product(*((self,)*n))
    def __rpow__(self, n):
        return cartesian_product(*((self,)*n))

class cartesian_product:
    def __init__(self, *args):
        self.elements = args
    def __len__(self):
        return reduce(operator.mul, map(len, self.elements))
    def __getitem__(self, n):
        return [e[i] for e, i  in zip(self.elements,self.get_indices(n))]
    def get_indices(self, n):
        sizes = map(len, self.elements)
        tmp = [0]*len(sizes)
        i = -1
        for w in reversed(sizes):
            tmp[i] = n % w
            n /= w
            i -= 1
        return tmp
    def __add__(self, arg):
        return mylist(map(None, self)+mylist(map(None, arg)))
    def __imul__(self, args):
        return mylist(self)*mylist(args)
    def __rmul__(self, args):
        return mylist(args)*mylist(self)
    def __mul__(self, args):
        if isinstance(args, cartesian_product):
            return cartesian_product(*(self.elements+args.elements))
        else:
            return cartesian_product(*(self.elements+(args,)))
    def __iter__(self):
        for i in xrange(len(self)):
            yield self[i]
    def __str__(self):
        return "[" + ",".join(str(i) for i in self) +"]"
    def __repr__(self):
        return "*".join(map(repr, self.elements))
于 2009-07-12T13:23:42.953 に答える
1

これは実際に作成したばかりですが、非常に便利なデバッグ ツールになると思います。

def dirValues(instance, all=False):
    retVal = {}
    for prop in dir(instance):
        if not all and prop[1] == "_":
            continue
        retVal[prop] = getattr(instance, prop)
    return retVal

私は通常、pdb コンテキストで dir() を使用しますが、これははるかに役立つと思います。

(pdb) from pprint import pprint as pp
(pdb) from myUtils import dirValues
(pdb) pp(dirValues(someInstance))
于 2011-11-20T19:39:03.640 に答える
0

デバッグするとき、基本的なエディターで文字列を表示したい場合があります。メモ帳で文字列を表示する場合:

import os, tempfile, subprocess

def get_rand_filename(dir_=os.getcwd()):
    "Function returns a non-existent random filename."
    return tempfile.mkstemp('.tmp', '', dir_)[1]

def open_with_notepad(s):
    "Function gets a string and shows it on notepad"
    with open(get_rand_filename(), 'w') as f:
        f.write(s)
        subprocess.Popen(['notepad', f.name])
于 2012-10-07T15:13:47.557 に答える