Pylons Webアプリケーションでは、「< 3,45,46,48-51,77」などの文字列を使用して、実際にオブジェクトのIDであるintのリストを作成する必要があります。の検索。Pythonで番号範囲を解釈する
これを行う方法に関する提案はありますか?私はPythonを初めて使いました。この種のことに役立つものは何も見つかりませんでした。
リストは次のようになります[1、2、3、45、46、48、49、50、51、77]
Pylons Webアプリケーションでは、「< 3,45,46,48-51,77」などの文字列を使用して、実際にオブジェクトのIDであるintのリストを作成する必要があります。の検索。Pythonで番号範囲を解釈する
これを行う方法に関する提案はありますか?私はPythonを初めて使いました。この種のことに役立つものは何も見つかりませんでした。
リストは次のようになります[1、2、3、45、46、48、49、50、51、77]
使用parseIntSet here
からIもでpyparsing実装など最後にコメントします。
parseIntSetは "< 3"型エントリを処理し、無効な文字列があればそれを吐き出すためにここで修正されています。
#! /usr/local/bin/python
import sys
import os
# return a set of selected values when a string in the form:
# 1-4,6
# would return:
# 1,2,3,4,6
# as expected...
def parseIntSet(nputstr=""):
selection = set()
invalid = set()
# tokens are comma seperated values
tokens = [x.strip() for x in nputstr.split(',')]
for i in tokens:
if len(i) > 0:
if i[:1] == "<":
i = "1-%s"%(i[1:])
try:
# typically tokens are plain old integers
selection.add(int(i))
except:
# if not, then it might be a range
try:
token = [int(k.strip()) for k in i.split('-')]
if len(token) > 1:
token.sort()
# we have items seperated by a dash
# try to build a valid range
first = token[0]
last = token[len(token)-1]
for x in range(first, last+1):
selection.add(x)
except:
# not an int and not a range...
invalid.add(i)
# Report invalid tokens before returning valid selection
if len(invalid) > 0:
print "Invalid set: " + str(invalid)
return selection
# end parseIntSet
print 'Generate a list of selected items!'
nputstr = raw_input('Enter a list of items: ')
selection = parseIntSet(nputstr)
print 'Your selection is: '
print str(selection)
そしてここでは、サンプルの実行からの出力です:
$ python qq.py
Generate a list of selected items!
Enter a list of items: <3, 45, 46, 48-51, 77
Your selection is:
set([1, 2, 3, 45, 46, 77, 48, 49, 50, 51])
まず、あなたが受け入れるだろう構文の種類を把握する必要があります。
シングル数:45、範囲内のオペレータより46
少ない
ダッシュ:現在のあなたの例では3つ持っている48-51
その後に、文字列をトークンに分割し、トークンの形式をチェックするだけです。
>>> print range.__doc__
range([start,] stop[, step]) -> list of integers
整数の算術的な進展を含むリストを返します。 範囲(i、j)は[i、i + 1、i + 2、...、j-1]を返します。 start(!)の既定値は0です。 stepが指定されると、増分(または減分)が指定されます。 たとえば、range(4)は[0、1、2、3]を返します。終点は省略されています! これは、4つの要素のリストの正確なインデックスです。
>>> range(33,44)
[33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]
>>> range(1,3)
[1, 2]
あなたのリストを反復して範囲を適切に呼び出すことができると思います。
>>> def lessThan(n) :
... return range(n+1)
...
>>> lessThan(4)
[0, 1, 2, 3, 4]
>>> def toFrom(n,m):
... return range(n,m)
...
>>> toFrom(33,44)
[33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43]
は、次にコンマで文字列を分割し、各ビットのために、リストが返さcatenating、呼び出すために機能するかを把握するのに十分な、それを解析します。
これ以上のものはすべてあなたのために書いたでしょう。
rng = "<3, 45, 46, 48-51, 77"
ids = []
for x in map(str.strip,rng.split(',')):
if x.isdigit():
ids.append(int(x))
continue
if x[0] == '<':
ids.extend(range(1,int(x[1:])+1))
continue
if '-' in x:
xr = map(str.strip,x.split('-'))
ids.extend(range(int(xr[0]),int(xr[1])+1))
continue
else:
raise Exception, 'unknown range type: "%s"'%x
最近、アプリのために同様のことを行う必要がありました。
具体的な数値は必要ありませんが、与えられた数値が範囲内にあるかどうかを確認する方法として、ラムダに評価できるPython式に解析することを検討してください。例えば、<3, 5-10, 12
は、func=(lambda x:x<3 or (5 <= x <= 10) or x==12))
とすることができます。それでラムダ、func(11)
を呼び出して11がそこに属しているかどうかを調べることができます。
"<3"の機能はありませんが、実際には "1-3"または "0-3"なので追加できる機能です。 +1。 – paxdiablo
"<3"機能をベースラインコードに追加しました。 – paxdiablo
import sysとosが使われていないのはなぜですか? – vartec