Как отсортировать словарь по значению?

У меня есть словарь значений, считанных из двух полей в базе данных: поле строки и числовое поле. Строковое поле уникально, поэтому это ключ словаря.

Я могу сортировать по ключам, но как я могу сортировать на основе значений?

Примечание. Я прочитал вопрос о переполнении стека Как отсортировать список словарей по значениям словаря в Python? и, возможно, может изменить мой код, чтобы иметь список словарей, но поскольку мне действительно не нужен список словарей, я хотел бы знать, есть ли более простое решение.

3065
задан 05 марта '09 в 3:49
источник поделиться
42 ответов
  • 1
  • 2

Невозможно отсортировать словарь, только чтобы получить представление отсортированного словаря. Словари по своей природе являются бесхозными, но другие типы, такие как списки и кортежи, не являются. Поэтому вам нужен упорядоченный тип данных для представления отсортированных значений, которые будут списком, возможно, списком кортежей.

Например,

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x будет списком кортежей, отсортированных по второму элементу в каждом кортеже. dict(sorted_x) == x.

И для тех, кто хочет сортировать ключи вместо значений:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

В Python3, поскольку распаковка не разрешена [1], мы можем использовать

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_by_value = sorted(x.items(), key=lambda kv: kv[1])
3697
ответ дан 05 марта '09 в 3:59
источник

Проще, чем: sorted(dict1, key=dict1.get)

Ну, на самом деле можно сделать "сортировку по значениям словаря". Недавно мне пришлось сделать это в Code Golf (вопрос Code golf: частотная диаграмма слов). Сокращенный, проблема была такой: учитывая текст, подсчитывайте, как часто встречается каждое слово, и отображает список верхних слов, отсортированных по уменьшению частоты.

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

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
  d[w] += 1

тогда вы можете получить список слов, упорядоченных по частоте использования с помощью sorted(d, key=d.get) - сортировка выполняется по клавишам словаря, используя количество вхождений слов в качестве ключа сортировки.

for w in sorted(d, key=d.get, reverse=True):
  print w, d[w]

Я пишу это подробное объяснение, чтобы проиллюстрировать, что люди часто подразумевают под "Я могу легко сортировать словарь по ключевым словам, но как я сортирую по значению" - и я думаю, что ОП пытался решить такую ​​проблему. И решение состоит в том, чтобы выполнить сортировку списка ключей на основе значений, как показано выше.

996
ответ дан 05 июля '10 в 11:01
источник

Вы можете использовать:

sorted(d.items(), key=lambda x: x[1])

Это сортирует словарь по значениям каждой записи в словаре от наименьшего до самого большого.

624
ответ дан 13 февр. '10 в 19:33
источник

Диктов нельзя сортировать, но вы можете создать из них отсортированный список.

Сортированный список значений dict:

sorted(d.values())

Список пар (ключ, значение), отсортированный по значению:

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))
175
ответ дан 05 марта '09 в 4:05
источник

В последнем Python 2.7 у нас есть новый OrderedDict, который запоминает порядок, в котором были добавлены элементы.

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1

>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

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

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

OrderedDict ведет себя как обычный dict:

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4

>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])
134
ответ дан 05 июля '10 в 5:50
источник

ОБНОВЛЕНИЕ: 5 ДЕКАБРЯ 2015 г. с использованием Python 3.5

В то время как я нашел приемлемый ответ полезным, я также был удивлен, что он не был обновлен до ссылки OrderedDict из стандартной библиотеки коллекций как жизнеспособной, современной альтернативы - предназначенной для решения именно такого рода проблем.

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

Официальная документация OrderedDict также предлагает очень похожий пример, но с использованием лямбда для функции сортировки

# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
79
ответ дан 05 дек. '15 в 12:46
источник

Часто бывает очень удобно использовать namedtuple. Например, у вас есть словарь "имя" в качестве ключей и "оценка" в качестве значений, и вы хотите сортировать по "оценке":

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

сортировка с наименьшей оценкой сначала:

worst = sorted(Player(v,k) for (k,v) in d.items())

сортировка с наивысшим рангом:

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

Теперь вы можете получить имя и оценку, скажем, второй лучший игрок (index = 1) очень Pythonically следующим образом:

player = best[1]
player.name
    'Richard'
player.score
    7
66
ответ дан 30 авг. '11 в 3:30
источник

В значительной степени то же, что и ответ Хэнк Гей;


    sorted([(value,key) for (key,value) in mydict.items()])

Или немного оптимизирован, как предложил Джон Фухи;


    sorted((value,key) for (key,value) in mydict.items())

60
ответ дан 05 марта '09 в 4:06
источник

По Python 3.6 будет установлен встроенный dict

Хорошие новости, поэтому исходный пример использования OP-карт, полученных из базы данных с уникальными идентификаторами строк в виде ключей и числовых значений в виде значений во встроенный Python v3.6 + dict, должен теперь уважать порядок вставки.

Если скажем, что в результате двух выражений таблицы столбцов из запроса базы данных, например:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

будет храниться в двух кортежах Python, k_seq и v_seq (выровненных по числовому индексу и с той же длиной курса), затем:

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

Разрешить вывод позже:

for k, v in ordered_map.items():
    print(k, v)

уступая в этом случае (для нового встроенного языка Python 3.6+!):

foo 0
bar 1
baz 42

в том же порядке на значение v.

Где в Python 3.5, установленном на моей машине, он в настоящее время дает:

bar 1
foo 0
baz 42

Детали:

Как было предложено в 2012 году Раймондом Хеттингером (см. письмо на python-dev с темой "Более компактные словари с более быстрой итерацией" ) и теперь (в 2016 году), анонсированный в письме Виктора Стинера на python-dev с темой "Python 3.6 dict становится компактным и получает личную версию, а ключевые слова становятся упорядоченными" из-за исправления/реализации проблемы 27350 "Компактный и упорядоченный диктов" в Python 3.6 мы теперь сможем использовать встроенную -in dict для поддержания порядка вставки!

Надеемся, это приведет к реализации тонкого слоя OrderedDict в качестве первого шага. Как указал @JimFasarakis-Hilliard, некоторые из них видят также случаи использования типа OrderedDict в будущем. Я думаю, что сообщество Python в целом будет тщательно проверять, если это выдержит испытание временем и какие будут следующие шаги.

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

  • Аргументы ключевого слова и
  • (промежуточное) хранилище dict

Первое, потому что в некоторых случаях облегчает отправку в реализации функций и методов.

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

Раймонд Хеттингер любезно предоставил документацию, объясняющую " The Tech Behind Python 3.6 Dictionaries" - из его Сан Франсиско Питон Meetup Group презентации 2016-DEC-08.

И, может быть, некоторые страницы с высоким разрешением и ответы на вопросы Qaru получат варианты этой информации, и многие высококачественные ответы потребуют обновления для каждой версии.

Caveat Emptor (но также см. ниже обновление 2017-12-15):

Как @ajcr справедливо отмечает: "Приоритет сохранения этой новой реализации рассматривается как деталь реализации и на нее нельзя положиться". (из whatsnew36) не nit picking, , но цитата была отрезана немного пессимистично;-). Он продолжается как "(это может измениться в будущем, но желательно, чтобы эта новая реализация dict на языке для нескольких выпусков до изменения спецификации языка для мандатной семантики сохранения порядка для всех текущих и будущих реализаций Python, это также помогает сохранить обратную совместимость со старыми версиями языка, где по-прежнему действует случайный порядок итераций, например Python 3.5).

Так, как и на некоторых человеческих языках (например, на немецком языке), использование формирует язык, и теперь будет объявлена ​​воля... в whatsnew36.

Обновление 2017-12-15:

В почте в список python-dev, Guido van Rossum заявил:

Сделайте так. "Dict сохраняет порядок вставки" - это решение. Благодарю!

Итак, версия 3.6 CPython побочный эффект упорядочивания вставки dict теперь становится частью спецификации языка (и не только является только деталью реализации). Этот почтовый поток также выявил некоторые отличительные цели дизайна для collections.OrderedDict, как напомнил Раймонд Хеттингер во время обсуждения.

54
ответ дан 10 сент. '16 в 13:05
источник

Данный словарь

e = {1:39, 4:34, 7:110, 2:87}

Сортировка

sred = sorted(e.items(), key=lambda value: value[1])

Результат

[(4, 34), (1, 39), (2, 87), (7, 110)]

Вы можете использовать функцию лямбда для сортировки вещей по значению и сохранения их в переменной, в данном случае sred с e исходным словарем.

Надеюсь, что это поможет!

41
ответ дан 25 янв. '16 в 17:54
источник

У меня была та же проблема, и я решил это следующим образом:

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(Люди, которые отвечают "Невозможно сортировать дикт", не читали вопрос! На самом деле, "я могу сортировать по ключам, но как я могу сортировать на основе значений?" явно означает, что он хочет список ключей, отсортированных по значению их значений.)

Обратите внимание, что порядок не определен (ключи с одинаковым значением будут в произвольном порядке в выходном списке).

37
ответ дан 18 нояб. '10 в 17:19
источник

В Python 2.7 просто выполните:

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

copy-paste из: http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

Наслаждайтесь; -)

31
ответ дан 22 авг. '13 в 11:38
источник

Это код:

import operator
origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
    print foo

print "\n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
    print foo

print "\n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
    print foo

Вот результаты:

Оригинал

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

Rofl

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

Ранг

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
23
ответ дан 08 марта '11 в 5:06
источник

Если значения являются числовыми, вы также можете использовать счетчик из коллекций

from collections import Counter

x={'hello':1,'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]    
22
ответ дан 27 июня '12 в 18:43
источник

Технически словари не являются последовательностями и поэтому не могут быть отсортированы. Вы можете сделать что-то вроде

sorted(a_dictionary.values())

Предполагая, что производительность не является огромной сделкой.

20
ответ дан 05 марта '09 в 3:56
источник

Вы можете создать "инвертированный индекс", также

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

Теперь ваш обратный имеет значения; каждое значение имеет список применимых клавиш.

for k in sorted(inverse):
    print k, inverse[k]
18
ответ дан 05 марта '09 в 4:52
источник

Попробуйте следующий подход. Определим словарь под названием mydict со следующими данными:

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

Если вы хотите отсортировать словарь по клавишам, можно сделать что-то вроде:

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

Это должно возвращать следующий результат:

alan: 2
bob: 1
carl: 40
danny: 3

С другой стороны, если нужно отсортировать словарь по значению (как задано в вопросе), можно было бы сделать следующее:

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

Результат этой команды (сортировка словаря по значению) должен вернуть следующее:

bob: 1
alan: 2
danny: 3
carl: 40
18
ответ дан 07 апр. '14 в 7:46
источник

Вы можете использовать collections.Counter. Обратите внимание, что это будет работать как для числовых, так и для нечисловых значений.

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])
18
ответ дан 09 марта '13 в 15:30
источник

Это возвращает список пар ключ-значение в словаре, отсортированный по значению от наивысшего до самого низкого:

sorted(d.items(), key=lambda x: x[1], reverse=True)

Для словаря, отсортированного по ключу, используйте следующее:

sorted(d.items(), reverse=True)

Возврат - это список кортежей, потому что сами словари не могут быть отсортированы.

Это может быть как напечатано, так и отправлено в дальнейшие вычисления.

15
ответ дан 12 февр. '14 в 23:10
источник

Вы можете использовать skip dict, который является словарем, который постоянно сортируется по значению.

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

Если вы используете keys(), values() или items(), тогда вы будете перебирать отсортированный порядок по значению.

Он реализован с использованием списка пропусков в datastructure.

14
ответ дан 26 сент. '14 в 1:56
источник
from django.utils.datastructures import SortedDict

def sortedDictByKey(self,data):
    """Sorted dictionary order by key"""
    sortedDict = SortedDict()
    if data:
        if isinstance(data, dict):
            sortedKey = sorted(data.keys())
            for k in sortedKey:
                sortedDict[k] = data[k]
    return sortedDict
13
ответ дан 01 нояб. '10 в 15:16
источник

Вы также можете использовать настраиваемую функцию, которая может быть передана клавише.

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

Еще один способ сделать это - использовать функцию labmda

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda t: t[1])
12
ответ дан 25 мая '17 в 21:13
источник

Вот решение, использующее zip на d.values() и d.keys(). Несколько строк вниз по этой ссылке (на объектах словаря):

Это позволяет создавать пары (значение, ключ), используя zip(): pairs = zip (d.values ​​(), d.keys()).

Итак, мы можем сделать следующее:

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]
9
ответ дан 20 июня '15 в 4:44
источник

Используйте ValueSortedDict из dicts:

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
7
ответ дан 19 окт. '11 в 9:25
источник

Я придумал этот,

import operator    
x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_x = {k[0]:k[1] for k in sorted(x.items(), key=operator.itemgetter(1))}

Для Python 3.x: x.items() вместо iteritems().

>>> sorted_x
{0: 0, 1: 2, 2: 1, 3: 4, 4: 3}

Или попробуйте с помощью collections.OrderedDict!

x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
from collections import OrderedDict

od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))
6
ответ дан 08 мая '13 в 11:17
источник

Вы можете использовать отсортированную функцию Python

sorted(iterable[, cmp[, key[, reverse]]])

Таким образом, вы можете использовать:

sorted(dictionary.items(),key = lambda x :x[1])

Перейдите по этой ссылке для получения дополнительной информации о отсортированной функции: https://docs.python.org/2/library/functions.html#sorted

6
ответ дан 21 нояб. '14 в 18:04
источник

Итерации через dict и сортировка по его значениям в порядке убывания:

$ python --version
Python 3.2.2

$ cat sort_dict_by_val_desc.py 
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for word in sorted(dictionary, key=dictionary.get, reverse=True):
  print(word, dictionary[word])

$ python sort_dict_by_val_desc.py 
aina 5
tuli 4
joka 3
sana 2
siis 1
6
ответ дан 30 окт. '11 в 22:42
источник

Конечно, помните, что вам нужно использовать OrderedDict потому что обычные словари Python не сохраняют первоначальный порядок.

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key = lambda x: x[1]))

Если у вас нет Python 2.7 или выше, лучшее, что вы можете сделать, это перебрать значения в функции генератора. (Существует OrderedDict для 2.4 и 2.6 здесь, но

a) I don't know about how well it works 

а также

b) You have to download and install it of course. If you do not have administrative access, then I'm afraid the option out.)

def gen(originalDict):
    for x,y in sorted(zip(originalDict.keys(), originalDict.values()), key = lambda z: z[1]):
        yield (x, y)
    #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 

for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

Вы также можете распечатать каждое значение

for bleh, meh in gen(myDict):
    print(bleh,meh)

Не забудьте удалить скобки после печати, если не используете Python 3.0 или выше

6
ответ дан 31 июля '15 в 11:08
источник

Как отметил Dilettant, Python 3.6 теперь сохранит порядок! Я думал, что буду использовать функцию, которую я написал, что облегчает сортировку итерации (кортеж, список, dict). В последнем случае вы можете сортировать либо по ключам, либо по значению, и это может учитывать числовое сравнение. Только для >= 3.6!

Когда вы пытаетесь использовать сортировку по итерации, которая хранится, например. строки, а также ints, sorted() не удастся. Конечно, вы можете принудительно провести сравнение строк с str(). Однако в некоторых случаях вы хотите сделать фактическое числовое сравнение, где 12 меньше, чем 20 (что не так в сравнении строк). Поэтому я придумал следующее. Если вам требуется явное числовое сравнение, вы можете использовать флаг num_as_num, который будет пытаться выполнять явную количественную сортировку, пытаясь преобразовать все значения в float. Если это удастся, оно будет выполнять числовую сортировку, иначе оно будет использоваться для сравнения строк.

Комментарии для улучшения или push-запросы приветствуются.

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")
6
ответ дан 02 марта '18 в 19:48
источник

Если ваши значения являются целыми числами, и вы используете Python 2.7 или новее, вы можете использовать collections.Counter вместо dict. Метод most_common даст вам все элементы, отсортированные по значению.

5
ответ дан 24 янв. '12 в 22:28
источник
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос