Чтобы удалить зазор под изображением, вы можете:
vertical-align: bottom;
vertical-align: top;
или vertical-align: middle;
display:block;
См. следующий код для живой демонстрации:
#vAlign img {
vertical-align :bottom;
}
#block img{
display:block;
}
div {border: 1px solid red;width:100px;}
img {width:100px;}
No fix:
With vertical-align:bottom; on image:
With display:block; on image:
Разрыв или дополнительное пространство под изображением не является ошибкой или проблемой, это поведение по умолчанию. Основная причина заключается в том, что изображения заменяются элементами ( см. MDN и W3C ). Это позволяет им «действовать как изображение» и иметь собственные собственные размеры, соотношение сторон ... Браузеры вычисляют свое свойство отображения inline
, но они придают им особое поведение, которое приближает их к элементам inline-block
(так как вы
Это также означает, что:
[...] когда изображения используются во встроенном контексте форматирования с выравниванием по вертикали: базовая линия, нижняя часть изображения будет отображаться на базовой линии контейнера. ( source: MDN , focus mine )
Поскольку браузеры по умолчанию вычисляют свойство vertical-align для базовой линии, это значение по умолчанию поведение. На следующем изображении показано, где базовая линия находится по тексту:
[/g15]
Элементы, выровненные по базовой линии, должны содержать место для дескрипторов которые простираются ниже базовой линии (например,
j, p, g ...
), как вы можете видеть на приведенном выше изображении. В этой конфигурации нижняя часть изображения выравнивается по базовой линии, как вы можете видеть в этом примере:
div{border:1px solid red;} img{width:100px;height:auto;}
jpq are letters with descenderВот почему поведение по умолчанию тега
создает пробел в нижней части его контейнера и почему изменение свойства вертикального выравнивания или свойства отображения удаляет его, как в следующей демонстрации:
div {width: 100px;border: 1px solid red;} img {width: 100px;height: auto;} .block img{ display:block; } .bottom img{ vertical-align:bottom; }
Default:
With display:block;
With vertical-align:bottom;
Один классический подход к этой проблеме - использовать «украшать, сортировать, дебекорировать» идиому, что особенно просто с использованием встроенной функции zip
на основе python:
>>> list1 = [3,2,4,1, 1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> list1, list2 = zip(*sorted(zip(list1, list2)))
>>> list1
(1, 1, 2, 3, 4)
>>> list2
('one', 'one2', 'two', 'three', 'four')
Это, конечно, больше нет списков, но это легко исправить, если это имеет значение:
>>> list1, list2 = (list(t) for t in zip(*sorted(zip(list1, list2))))
>>> list1
[1, 1, 2, 3, 4]
>>> list2
['one', 'one2', 'two', 'three', 'four']
Стоит отметить, что вышеизложенное может пожертвовать скоростью для терпения; версия на месте, которая занимает 3 строки, немного медленнее на моей машине для небольших списков:
>>> %timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 3.3 us per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best of 3: 2.84 us per loop
С другой стороны, для больших списков однострочная версия может быть быстрее :
>>> %timeit zip(*sorted(zip(list1, list2)))
100 loops, best of 3: 8.09 ms per loop
>>> %timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100 loops, best of 3: 8.51 ms per loop
Как указывает Quantum7, предложение JSF немного быстрее, но, вероятно, это будет только немного быстрее, потому что Python использует очень ту же внутреннюю идентификацию DSU для всех видов на основе ключей. Это просто немного ближе к голым металлам. (Это показывает, насколько хорошо оптимизированы подпрограммы zip
!) [/ G6]
Я думаю, что подход на основе zip
более гибкий и немного читаем, поэтому я предпочитаю его.
Как насчет:
list1 = [3,2,4,1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
sortedRes = sorted(zip(list1, list2), key=lambda x: x[0]) # use 0 or 1 depending on what you want to sort
>>> [(1, 'one'), (1, 'one2'), (2, 'two'), (3, 'three'), (4, 'four')]
Я использовал ответ, полученный senderle в течение длительного времени, пока не обнаружил np.argsort
. Вот как это работает.
# idx works on np.array and not lists.
list1 = np.array([3,2,4,1])
list2 = np.array(["three","two","four","one"])
idx = np.argsort(list1)
list1 = np.array(list1)[idx]
list2 = np.array(list2)[idx]
Я нахожу это решение более интуитивным, и он работает очень хорошо. Производительность:
def sorting(l1, l2):
# l1 and l2 has to be numpy arrays
idx = np.argsort(l1)
return l1[idx], l2[idx]
# list1 and list2 are np.arrays here...
%timeit sorting(list1, list2)
100000 loops, best of 3: 3.53 us per loop
# This works best when the lists are NOT np.array
%timeit zip(*sorted(zip(list1, list2)))
100000 loops, best of 3: 2.41 us per loop
# 0.01us better for np.array (I think this is negligible)
%timeit tups = zip(list1, list2); tups.sort(); zip(*tups)
100000 loops, best for 3 loops: 1.96 us per loop
Несмотря на то, что np.argsort
не самый быстрый, я считаю его более удобным.
TypeError: only integer arrays with one element can be converted to an index
(Python 2.7.6, numpy 1.8.2). Чтобы исправить это, list1 и list2 должны быть объявлены как массивы numpy.
– BenB
7 July 2015 в 00:53
np.argsort
не пытаются преобразовать в np.array
внутренне.
– Daniel Thaagaard Andreasen
7 July 2015 в 12:37
Вы можете использовать функции zip()
и sort()
для выполнения этого:
Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01)
[GCC 4.3.4 20090804 (release) 1] on cygwin
>>> list1 = [3,2,4,1,1]
>>> list2 = ['three', 'two', 'four', 'one', 'one2']
>>> zipped = zip(list1, list2)
>>> zipped.sort()
>>> slist1 = [i for (i, s) in zipped]
>>> slist1
[1, 1, 2, 3, 4]
>>> slist2 = [s for (i, s) in zipped]
>>> slist2
['one', 'one2', 'two', 'three', 'four']
Надеемся, что это поможет
Вы можете сортировать индексы, используя значения в качестве ключей:
indexes = range(len(list1))
indexes.sort(key=list1.__getitem__)
Чтобы получить отсортированные списки с отсортированными индексами:
sorted_list1 = map(list1.__getitem__, indexes)
sorted_list2 = map(list2.__getitem__, indexes)
В вашем случае вы не должны иметь list1
, list2
, а скорее один список пар:
data = [(3, 'three'), (2, 'two'), (4, 'four'), (1, 'one'), (1, 'one2')]
Его легко создать; его легко сортировать в Python:
data.sort() # sort using a pair as a key
Сортировать по первому значению:
data.sort(key=lambda pair: pair[0])
Преобразование Шварца . Встроенная сортировка Python стабильна, поэтому два 1
s не вызывают проблемы.
>>> l1 = [3, 2, 4, 1, 1]
>>> l2 = ['three', 'two', 'four', 'one', 'second one']
>>> zip(*sorted(zip(l1, l2)))
[(1, 1, 2, 3, 4), ('one', 'second one', 'two', 'three', 'four')]
Один из способов - отслеживать, куда идет каждый индекс, сортируя идентификатор [0,1,2, .. n]
Это работает для любого количества списков.
Затем переместите каждый элемент в свое положение. Использование сплайсов лучше всего.
list1 = [3,2,4,1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']
index = range(len(list1))
print index
'[0, 1, 2, 3, 4]'
index.sort(key = list1.__getitem__)
print index
'[3, 4, 1, 0, 2]'
list1[:] = [list1[i] for i in index]
list2[:] = [list2[i] for i in index]
print list1
print list2
'[1, 1, 2, 3, 4]'
"['one', 'one2', 'two', 'three', 'four']"
Обратите внимание, что мы могли бы повторить списки без их сортировки:
list1_iter = (list1[i] for i in index)
Вы можете использовать аргумент ключа в методе sorted (), если у вас нет двух одинаковых значений в списке2.
Код приведен ниже:
sorted(list2, key = lambda x: list1[list2.index(x)])
Сортирует list2 согласно к соответствующим значениям в списке1, но убедитесь, что при использовании этого значения два значения в списке2 не равны, потому что функция list.index () дает первое значение
*
делает распаковку аргументов , – senderle 19 March 2012 в 17:46