Существует ли лучшее, pythonic способ сделать это?

Нет, не непосредственно. Резервные копии базы данных SQL Server 2008 не обратно совместимы с SQL Server 2005. Однако с Studio управления SQL Server 2008 года, можно написать сценарий данных и схем в режиме SQL Server 2005. Этот статья описывает процесс подробно.

10
задан Peter 20 October 2009 в 23:05
поделиться

8 ответов

строка кода:

adDict[adId] = set(userId)

вряд ли сделает то, что вы хотите - она ​​будет обрабатывать строку userId как последовательность букв, например, if userId было aleax , вы бы получили набор из четырех элементов, как, скажем, set (['a', 'l', 'e', ​​'x'] ) . Позже .add (userId) , когда userId равен aleax , снова добавится пятый элемент, строка 'aleax' , потому что .add (в отличие от инициализатора набора, который принимает итерацию в качестве аргумента) принимает в качестве аргумента один элемент.

Чтобы создать набор из одного элемента, используйте set ([ userId]) .

Это довольно частая ошибка, поэтому я хотел объяснить ее четко. Что, как говорится,

10
ответ дан 3 December 2019 в 13:32
поделиться

Поздравляем, у вас очень хороший код. Есть несколько небольших приемов, которые вы можете использовать, чтобы сделать его короче / проще.

Существует изящный тип объекта, называемый defaultdict, который предоставляется модулем коллекций. Вместо того, чтобы проверять, есть ли в adDict ключ adId, вы можете настроить defaultdict, который действует как обычный dict, за исключением того, что он автоматически предоставляет вам пустой set (), когда нет ключа. Таким образом, вы можете изменить

if ( adId in adDict ):
    adDict[adId].add(userId)
else:
    adDict[adId] = set(userId)

на просто

adDict[adId].add(userId)

. Кроме того, вместо

for row in reader:
    adId = row[0]
    userId = row[1]

вы можете сократить это до

for adId,userId in reader:

Редактировать: Как Паркер любезно отмечает в комментариях,

for key, value in adDict.iteritems():

является наиболее эффективным способом перебирать dict, если вы собираетесь использовать оба ключ и значение в цикле. В Python3 вы можете использовать

for key, value in adDict.items():

, поскольку items () возвращает итератор.

#!/usr/bin/env python
import csv
from collections import defaultdict

adDict = defaultdict(set)
reader = csv.reader(open("some.csv"), delimiter=' ')
for adId,userId in reader:
    adDict[adId].add(userId)
for key,value in adDict.iteritems():
    print (key, ',' , len(value))
18
ответ дан 3 December 2019 в 13:32
поделиться

Вы можете сократить цикл for до следующего:

for row in reader:
  adDict.setdefault(row[0], set()).add(row[1])
7
ответ дан 3 December 2019 в 13:32
поделиться

Вместо:

for row in reader:
    adId = row[0]
    userId = row[1]

Использовать автоматическую распаковку последовательности:

for (adId, userId) in reader:

В:

if ( adId in adDict ):

Вам не нужны скобки.

Вместо:

if ( adId in adDict ):
    adDict[adId].add(userId)
else:
    adDict[adId] = set(userId)

Используйте defaultdict :

from collections import defaultdict
adDict = defaultDict(set)

# ...

adDict[adId].add(userId)

Или, если преподаватель не разрешил вам использовать другие модули, используйте setdefault () :

adDict.setdefault(adId, set()).add(userId)

При печати:

for key, value in adDict.items():
    print (key, ',' , len(value))

Использование строкового форматирования может быть проще для форматирования:

print "%s,%s" % (key, len(value))

Или, если вы используете Python 3:

print ("{0},{1}".format (key, len(value)))
3
ответ дан 3 December 2019 в 13:32
поделиться

Поскольку у вас есть только файл с разделителями-пробелами, я бы сделал:

from __future__ import with_statement
from collections import defaultdict

ads = defaultdict(set)
with open("some.csv") as f:
    for ad, user in (line.split(" ") for line in f):
        ads[ad].add(user)

for ad in ads:
    print "%s, %s" % (ad, len(ads[ad]))
3
ответ дан 3 December 2019 в 13:32
поделиться

Единственные изменения I 'd make извлекают сразу несколько элементов из считывателя и используют строковое форматирование для операторов печати. ​​

import csv

adDict = {}
reader = csv.reader(open("some.csv"), delimiter=' ')
# Can extract multiple elements from a list in the iteration statement:
for adId, userId in reader: 
    if ( adId in adDict ):
        adDict[adId].add(userId)
    else:
        adDict[adId] = set(userId)

for key, value in adDict.items():
    # I believe this gives you more control over how things are formatted:
    print ("%s, %d" % (key, len(value)))
1
ответ дан 3 December 2019 в 13:32
поделиться

Всего несколько кусочков:

Для извлечения списка строк в переменные:

adId, userId = row

Оператор if не требует фигурных скобок:

if adId in adDict:

Вы могли бы используйте исключения для обработки отсутствующего ключа в слове, но оба способа работают хорошо, например:

try:
    adDict[adId].add(userId)
except KeyError:
    adDict[adId] = set(userId)
1
ответ дан 3 December 2019 в 13:32
поделиться

Здесь есть несколько отличных ответов.

Один трюк, который мне особенно нравится, - это упростить повторное использование моего кода в будущем вот так

import csv

def parse_my_file(file_name):
     # some existing code goes here
     return aDict

if __name__ == "__main__":
     #this gets executed if this .py file is run directly, rather than imported
     aDict = parse_my_file("some.csv")
     for key, value in adDict.items():
         print (key, ',' , len(value))

Теперь вы можете импортировать парсер csv из другого модуля и получить программный доступ к aDict.

3
ответ дан 3 December 2019 в 13:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: