В настоящее время вы не можете написать понимание списка, которое было бы так легко прочитать, как ваш цикл for
. Вместо этого используйте itertools.accumulate
.
>>> list(accumulate(range(1,11), lambda acc, x: acc + 1/x))
[1, 1.5, 1.8333333333333333, 2.083333333333333, 2.283333333333333, 2.4499999999999997, 2.5928571428571425, 2.7178571428571425, 2.8289682539682537, 2.9289682539682538]
В Python 3.8 выражения присваивания позволят вам написать
% ./python.exe
Python 3.8.0a2 (tags/v3.8.0a2:23f4589b4b, Mar 18 2019, 15:16:44)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> m = 0
>>> [m := m + 1/x for x in range(1,11)]
[1.0, 1.5, 1.8333333333333333, 2.083333333333333, 2.283333333333333, 2.4499999999999997, 2.5928571428571425, 2.7178571428571425, 2.8289682539682537, 2.9289682539682538]
Обратите внимание, что m
необходимо инициализировать, прежде чем его можно будет использовать в понимании списка Тем не менее.
Я думаю, что это является главным образом выбирающим текущая культура потока.
Если Вы изменяете тест Marc для использования этой формы String.StartsWith
:
Stopwatch watch = Stopwatch.StartNew();
CultureInfo cc = CultureInfo.CurrentCulture;
for (int i = 0; i < LOOP; i++)
{
if (s1.StartsWith(s2, false, cc)) chk++;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
это прибывает намного ближе.
Если Вы используете s1.StartsWith(s2, StringComparison.Ordinal)
это намного быстрее, чем использование CompareInfo.IsPrefix
(в зависимости от CompareInfo
конечно). На моем поле результаты (не с научной точки зрения):
Очевидно, поэтому это действительно просто сравнивает целые числа на 16 битов в каждой точке, которая является довольно дешевой. Если бы Вы не хотите чувствительную к культуре проверку, и производительность особенно важна для Вас, это - перегрузка, которую я использовал бы.
Хороший вопрос; для теста я добираюсь:
9156ms; chk: 50000000
6887ms; chk: 50000000
Тестовая буровая установка:
using System;
using System.Diagnostics;
using System.Globalization;
class Program
{
static void Main()
{
string s1 = "abcdefghijklmnopqrstuvwxyz", s2 = "abcdefg";
const int LOOP = 50000000;
int chk = 0;
Stopwatch watch = Stopwatch.StartNew();
for (int i = 0; i < LOOP; i++)
{
if (s1.StartsWith(s2)) chk++;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
chk = 0;
watch = Stopwatch.StartNew();
CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;
for (int i = 0; i < LOOP; i++)
{
if (ci.IsPrefix(s1, s2)) chk++;
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds + "ms; chk: " + chk);
}
}
StartsWith называет IsPrefix внутренне. Это присваивает информацию о культуре прежде, чем назвать IsPrefix.