簡體   English   中英

如何用Python編寫這個片段?

[英]How to write this snippet in Python?

我正在學習Python(我有一個C / C ++背景)。

我需要在學習的同時用Python編寫實用的東西。 我有以下偽代碼(我第一次嘗試編寫Python腳本,因為昨天閱讀了Python)。 希望該片段詳細說明了我想要做的事情的邏輯。 BTW我在Ubuntu Karmic上使用python 2.6。

假設腳本被調用為:script_name.py directory_path

import csv, sys, os, glob

# Can I declare that the function accepts a dictionary as first arg?
def getItemValue(item, key, defval)
  return !item.haskey(key) ? defval : item[key]


dirname = sys.argv[1]

# declare some default values here
weight, is_male, default_city_id = 100, true, 1 

# fetch some data from a database table into a nested dictionary, indexed by a string
curr_dict = load_dict_from_db('foo')

#iterate through all the files matching *.csv in the specified folder
for infile in glob.glob( os.path.join(dirname, '*.csv') ):
  #get the file name (without the '.csv' extension)
  code = infile[0:-4]
  # open file, and iterate through the rows of the current file (a CSV file)
  f = open(infile, 'rt')
  try:
    reader = csv.reader(f)
    for row in reader:
      #lookup the id for the code in the dictionary
      id = curr_dict[code]['id']
      name = row['name']
      address1 = row['address1']
      address2 = row['address2']
      city_id = getItemValue(row, 'city_id', default_city_id)

      # insert row to database table

  finally:
    f.close()

我有以下問題:

  1. 代碼是用Pythonic編寫的(有沒有更好的實現方法)?

  2. 給定一個具有如下所示的模式的表,我如何編寫一個從表中獲取數據的Python函數,並返回在由string(name)索引的字典中。

  3. 如何將行數據插入表中(實際上我想盡可能使用事務,並在文件關閉之前提交)

表模式:

create table demo (id int, name varchar(32), weight float, city_id int);

順便說一句,我的后端數據庫是postgreSQL

[編輯]

Wayne等人:

為了澄清,我想要的是一組行。 每一行都可以用鍵索引(這意味着行容器是一個字典(右)?好了,現在一旦我們使用鍵檢索了一行,我也希望能夠訪問'列'中的'行 - 意味着行數據本身就是一個字典。我不知道Python在處理字典時是否支持多維數組語法 - 但以下語句將有助於解釋我打算如何在概念上使用從db返回的數據。 dataset ['joe'] ['weight']將首先獲取由鍵'joe'(這是一個字典)索引的行數據,然后將該字典索引為鍵'weight'。我想知道如何構建這樣的以你之前的Pythonic方式從檢索到的數據中獲取字典字典。

一種簡單的方法是寫下這樣的東西:

import pyodbc

mydict = {}
cnxn = pyodbc.connect(params)
cursor = cnxn.cursor()
cursor.execute("select user_id, user_name from users"):

for row in cursor:
   mydict[row.id] = row

這是正確的/可以用更加pythonic的方式寫嗎?

從你需要使用的字典中獲取值.get方法的dict

>>> d = {1: 2}
>>> d.get(1, 3)
2
>>> d.get(5, 3)
3

這將消除對getItemValue函數的需要。 我不會評論現有的語法,因為它顯然與Python不同。 Python中三元的正確語法是:

true_val if true_false_check else false_val
>>> 'a' if False else 'b'
'b'

但正如我在下面所說,你完全不需要它。

如果您使用的是Python> 2.6,則應該在try-finally使用with語句:

with open(infile) as f:
    reader = csv.reader(f)
    ... etc

看到你想把row作為字典,你應該使用csv.DictReader而不是簡單的csv. reader csv. reader 但是,在您的情況下,這是不必要的。 您的sql查詢可以構造為訪問row dict的字段。 在這種情況下,您不需要創建單獨的項目city_idname等。要將默認的city_id添加到row如果它不存在),您可以使用.setdefault方法:

>>> d
{1: 2}
>>> d.setdefault(1, 3)
2
>>> d
{1: 2}
>>> d.setdefault(3, 3)
3
>>> d
{1: 2, 3: 3}

對於id ,只需row[id] = curr_dict[code]['id']

切片時,您可以跳過0

>>> 'abc.txt'[:-4]
'abc'

通常,Python的庫在游標上提供fetchonefetchmanyfetchall方法,它們返回Row對象,可能支持類似dict的訪問或返回一個簡單的元組。 這取決於您使用的特定模塊。

看起來Pythonic對我來說足夠了。

三元操作應該看起來像這樣(我認為這將返回您期望的結果):

return defval if not key in item else item[key]

是的,您可以基本上以任何順序傳遞字典(或任何其他值)。 唯一的區別是如果你使用* args,** kwargs(通過約定命名。技術上你可以使用你想要的任何名稱),它們應該按順序排列,最后一個或兩個參數。

要插入DB,您可以使用odbc模塊:

import odbc
conn = odbc.odbc('servernamehere')
cursor = conn.cursor()
cursor.execute("INSERT INTO mytable VALUES (42, 'Spam on Eggs', 'Spam on Wheat')")
conn.commit()

你可以在odbc模塊上閱讀或找到大量的例子 - 我確信還有其他模塊,但是那個應該可以正常工作。

如需檢索,您可以使用

cursor.execute("SELECT * FROM demo")
#Reads one record - returns a tuple
print cursor.fetchone()
#Reads the rest of the records - a list of tuples
print cursor.fetchall()

將其中一條記錄寫入字典:

record = cursor.fetchone()
# Removes the 2nd element (at index 1) from the record
mydict[record[1]] = record[:1] + record[2:]

雖然如果你想要整個shebang,它幾乎會為生成器表達而尖叫

mydict = dict((record[1], record[:1] + record[2:] for record in cursor.fetchall())

它應該使用名稱作為鍵,將所有記錄整齊地打包在字典中。

HTH

后所需要的結腸def S:

def getItemValue(item, key, defval):
    ...

布爾運算符:在python中! - > not ; && - > and and || - > or (有關布爾運算符,請參閱http://docs.python.org/release/2.5.2/lib/boolean.html )。 沒有? : ? : python中的運算符,有一個return (x) if (x) else (x)表達式,雖然我個人很少使用它而支持plain if

booleans / None TrueFalseNone都有大寫字母。

檢查參數類型:在python中,通常不會聲明函數參數的類型。 你可以去assert isinstance(item, dict), "dicts must be passed as the first parameter!" 在函數中雖然經常不鼓勵這種“嚴格檢查”,因為它在python中並不總是必要的。

python關鍵字: default不是保留的python關鍵字 ,可以作為參數和變量使用(僅供參考)。

樣式指南: PEP 8 (python樣式指南)規定模塊import通常應該只是每行一個,盡管有一些例外(我必須承認我經常不在單獨的行上遵循import sysos ,盡管我通常會遵循它。)

文件打開模式: rt在python 2.x中無效 - 它會起作用,但t將被忽略。 另請參見http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files 它在python 3中是有效的 ,所以我不認為如果你想強制文本模式,在二進制字符上引發異常就會受到影響(如果你想讀取非ASCII字符,請使用rb 。)

使用字典: Python過去常常使用dict.has_key(key)但是你現在應該key in dict使用key in dict (它已經在很大程度上取代了它,請參閱http://docs.python.org/library/stdtypes.html#mapping-types- dict 。)

分割文件擴展名: code = infile[0:-4]可以替換為code = os.path.splitext(infile)[0] (返回例如('root', '.ext')擴展名中的點(參見http://docs.python.org/library/os.path.html#os.path.splitext )。

編輯:刪除單行東西上的多個變量聲明並添加一些格式。 還糾正了rt在python 3中不是python中的有效模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM