Как я могу приблизить Python или оператор для сравнения набора в Scala?

Я предполагаю, что Вы на самом деле создаете дерево XML DOM, потому что Вы хотите проверить это, что входит в этот файл, допустимый XML, так как иначе Вы просто записали бы статическую строку в файл. Если проверка Вашего вывода является действительно Вашей целью, тогда я предложил бы

from xml.dom.minidom import parseString

doc = parseString("""<html>
    <head>
        <script type="text/javascript">
            var a = 'I love &amp;aacute; letters'
        </script>
    </head>
    <body>
        <h1>And I like the fact that 3 &gt; 1</h1>
    </body>
    </html>""")

with open("foo.xhtml", "w") as f:
    f.write( doc.toxml() )

, Это позволяет Вам просто записать XML, который Вы хотите произвести, для проверки этого это корректно (так как parseString повысит исключение, если это будет недопустимо), и имейте намного более хороший взгляд кода.

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

var a = '%(message)s'

и затем использовал бы оператор %, чтобы сделать замену, как

</html>""" % {"message": "I love &amp;aacute; letters"})
6
задан Thomas Jung 3 May 2012 в 14:24
поделиться

5 ответов

Итераторы также ленивы (хотя и не очень функциональны, так как их можно выполнять только один раз). Таким образом, вы можете сделать это следующим образом:

  def correct(word: String) = {
    val sets = List[String => Set[String]](
      x => known(Set(x)), x => known(edits1(x)), known_edits2
    ).elements.map(_(word))

    sets find { !_.isEmpty } match {
      case Some(candidates: Set[String]) => candidates.reduceLeft { (res, n) => if (NWORDS(res) > NWORDS(n)) res else n }
      case None => word
    }
  }

В качестве бонуса метод find () итератора не вызывает оценку следующего элемента.

2
ответ дан 8 December 2019 в 16:04
поделиться

Это сработает? Синтаксис _ является частично применяемой функцией, и, используя (ленивый) поток , я гарантирую, что оценки в reduceLeft (что я считаю более подходящим чем foldLeft здесь) происходит только по мере необходимости!

def correct(word:String) = {
  Stream(known(Set(word)) _, 
         known(edits1(word)) _, 
         known_edits2(word) _, 
         Set(word) _
         ).find( !_().isEmpty ) match {
    case Some(candidates) =>
      candidates.reduceLeft {(res, n) => if (NWORDS(res) > NWORDS(n)) res else n}
    case _ => "" //or some other value

}

Я, вероятно, допустил здесь некоторые синтаксические ошибки, но я думаю, что подход Stream является допустимым

4
ответ дан 8 December 2019 в 16:04
поделиться

Я не уверен, почему вы пытаетесь использовать ленивую оценку для , известного , а не просто использовать поток, как показано на примере oxbow_lakes. Лучший способ сделать то, что он сделал:

def correct(word: String) = {
  import Stream._

  val str = cons(known(Set(word)), 
            cons(known(edits1(word)),
            cons(known_edits2(word),
            cons(Set(word), empty))))

  str find { !_.isEmpty } match {
    case Some(candidates) =>
      candidates.foldLeft(Set[String]()) { (res, n) =>
        if (NWORDS(res) > NWORDS(n)) res else n
      }

    case None => Set()
  }
}

Эксплуатация того факта, что Stream.cons уже ленивый, поэтому нам не нужно оборачивать все в thunk.

If you ' мы действительно настроены на хороший синтаксис, мы можем добавить немного синтаксического сахара ко всем этим недостаткам:

implicit def streamSyntax[A](tail: =>Stream[A]) = new {
  def #::(hd: A) = Stream.cons(hd, tail)
}

Теперь наше ранее некрасивое str определение сводится к следующему:

def correct(word: String) = {
  val str = known(Set(word)) #:: known(edits1(word)) #::
            known_edits2(word) #:: Set(word) #:: Stream.empty

  ...
}
6
ответ дан 8 December 2019 в 16:04
поделиться

Готовность к Scala 2.7 (включая неявный обход производительности):

class Or[A](one: Set[A]) {
  def or(other: => Set[A]): Set[A] = if (one.isEmpty) other else one 
}

implicit def toOr[A](one: Set[A]) = new Or(one)

def correct(word: String) = {
  candidates = known(Set(word)) or known(edits1(word)) or known_edits2(word) or Set(word)
  candidates.foldLeft("") {(a, b) => if (NWORDS(a) > NWORDS(b)) a else b}
}

Качество Scala 2.8:

implicit def toOr[A](one: Set[A]) = new AnyRef { 
  def or(other: => Set[A]): Set[A] = if (one.isEmpty) other else one 
}

def correct(word: String) = {
  candidates = known(Set(word)) or known(edits1(word)) or known_edits2(word) or Set(word)
  candidates.max(Ordering.fromLessThan[String](NWORDS(_) < NWORDS(_)))
}

Тем не менее, я в значительной степени поддержал всех остальных. Я не рассматривал Stream .

EDIT

Кажется, Ordering.fromLessThan может привести к двойному количеству необходимых сравнений. Вот альтернативная версия для этой строки:

  candidates.max(new Ordering[String] { def compare(x: String, y: String) = NWORDS(x) - NWORDS(y) })
3
ответ дан 8 December 2019 в 16:04
поделиться

Я пытался реализовать короткую реализацию Scala корректора орфографии. Это 15 строк без импорта. Самая короткая замена для Python's или простой вызов по имени параметра:

def or[T](candidates : Seq[T], other : => Seq[T]) = if(candidates.isEmpty) other else candidates
def candidates(word: String) = or(known(List(word)), or(known(edits1(word)), known(edits2(word))))

В реальном мире я бы использовал неявное преобразование, предложенное Даниилом

.
0
ответ дан 8 December 2019 в 16:04
поделиться
Другие вопросы по тегам:

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