Обозначение => Type
означает вызов по имени, который является одним из параметров для многих способов , Если вы не знакомы с ними, я рекомендую потратить некоторое время на то, чтобы прочитать эту статью в Википедии, хотя в настоящее время это, главным образом, призыв к значению и вызов по ссылке.
Что это означает, что то, что передано, является замененным для имени значения внутри функции. Например, возьмите эту функцию:
def f(x: => Int) = x * x
Если я назову это так
var y = 0
f { y += 1; y }
Затем код будет выполняться следующим образом:
{ y += 1; y } * { y += 1; y }
Хотя это поднимает вопрос о том, что произойдет, если есть столкновение имени идентификатора. В традиционном вызове по имени используется механизм, называемый замещением захвата, чтобы избежать столкновений имен. Однако в Scala это реализовано по-другому с тем же результатом. Имена идентификаторов внутри параметра не могут ссылаться или теневые идентификаторы в вызываемой функции.
Есть некоторые другие моменты, связанные с вызовом по-имени, о котором я расскажу после объяснения двух других.
Синтаксис () => Type
обозначает тип a Function0
. То есть, функция, которая не принимает никаких параметров и что-то возвращает. Это эквивалентно, например, вызову метода size()
- он не принимает никаких параметров и возвращает число.
Интересно, однако, что этот синтаксис очень похож на синтаксис для анонимная функция literal , что является причиной некоторой путаницы. Например,
() => println("I'm an anonymous function")
является анонимным литералом функции arity 0, тип [] Таким образом, мы могли бы написать: Однако важно не путать тип со значением. На самом деле это всего лишь Рассмотрим, например, Что можно сделать с Поскольку Первым источником путаницы является мысль о сходстве между типом и литералом, который существует для 0- функции arity также существуют для вызова по имени. Другими словами, считая, что является литералом для будет литералом для Другой источник путаницы в том, что значение () => Unit
val f: () => Unit = () => println("I'm an anonymous function")
Единица => Тип
Function1
, чья первая параметр имеет тип Unit
. Другие способы написать это будут (Unit) => Type
или Function1[Unit, Type]
. Дело в том, что это вряд ли когда-либо будет тем, что нужно. Основная цель Unit
- указать значение, которое не интересует, поэтому не имеет смысла получать это значение. def f(x: Unit) = ...
x
? Он может иметь только одно значение, поэтому его не нужно получать. Одно из возможных применений - это функции цепочки, возвращающие Unit
: val f = (x: Unit) => println("I'm f")
val g = (x: Unit) => println("I'm g")
val h = f andThen g
andThen
определяется только на Function1
, а возвращаемые нами функции возвращаются Unit
, нам нужно было определить Источники путаницы
() => { println("Hi!") }
() => Unit
, тогда { println("Hi!") }
=> Unit
. Это не. Это блок кода , а не буквальный.
типа val f: () => Unit = () => println("I'm an anonymous function")
типа val f: () => Unit = () => println("I'm an anonymous function")
написано val f: () => Unit = () => println("I'm an anonymous function")
()
, которое выглядит как список параметров 0-arity (но это не так).
Чтобы подражать точному шаблону в вашей команде grep
, выполните
import re
pattern = re.compile('|'.join(key_words))
for log_line in log_lines:
if pattern.search(log_line):
print log_line
. Если вы хотите разрешить специальные символы, вам придется их избегать:
pattern = re.compile('|'.join(re.escape(word) for word in key_words))
Как вы можете себе представить, использование регулярных выражений в этом случае немного излишне. Вместо этого вы можете сделать прямой поиск. Вы можете использовать any
, чтобы помочь с поиском, так как он замкнут.
for log_line in log_lines:
if any(word in log_line for word in key_words):
print log_line
Выполняет линейный поиск всей строки для каждого ключевого слова. Вы можете сделать это немного более эффективным, если ключевые слова предназначены для фактических слов, тем более что у вас уже есть набор для ключевых слов:
for log_line in log_lines:
if keywords.intersection(set(log_line.split()):
print log_line
Одной из первых оптимизаций было бы фактически break
, как только вы нашли одно совпадение:
key_words = [ "one", "two", "three"]
log_lines = os.popen("logcat");
for log_line in log_lines:
for keyword in key_words:
if keyword in log_line:
print log_line
break # stop looking for keywords if you already found one
Более читабельное решение - заменить проверку цикла ключевого слова регулярным выражением. Если есть совпадение, выведите строку:
import re
key_words = [ "one", "two", "three"]
regex = re.compile('|'.join(key_words)) # one|two|three
log_lines = os.popen("logcat");
for log_line in log_lines:
if regex.match(log_line): # returns None if no match, an object if there is a match
print log_line
С точки зрения производительности, не уверен, что будет быстрее, но один будет более читабельным. Однако в результатах есть некоторые оговорки.
Привет, ты можешь использовать регулярное выражение и попробовать этот сценарий. Вы также можете изменить регулярное выражение в соответствии с приведенными ниже примерами проверки:
import re
key_words = [ "one", "two", "three"]
regex = "|".join(key_words)
log_lines = open("logcat", 'r')
lines = log_lines.readlines()
print filter(lambda x : re.search(regex,x), lines)
log_lines.close()
Предлагаемое решение печатает строки, содержащие несколько ключевых слов так же часто, как и количество ключевых слов, которые у вас есть, это может быть то, чего вы хотите избежать. Кроме того, если ключевое слово появляется как часть другого слова, оно также появляется (хотя это соответствует поведению grep).
Некоторые решения:
import os
key_words = {"one", "two", "three"}
log_lines = ['This has a one and a two', 'Some ones', 'This one has neither, oh it does', 'This does not', 'A three']
# fixing the repetition
for log_line in log_lines:
for keyword in key_words:
if keyword in log_line:
print(log_line)
break
# fixing the repetition and partial matches
for log_line in log_lines:
for word in log_line.split():
if word in key_words:
print(log_line)
break
# single line solution
print([log_line for log_line in log_lines if key_words & set(log_line.split()) != set()])
# single line solution with partial matches
print([log_line for log_line in log_lines if any(key_word in log_line for key_word in key_words)])