4
$\begingroup$

I have imported Alice in Wonderland into Mathematica. I have made a list of the sentences and further divided them into words. Now suppose, nominally, I have the following list:

l={{"alice's", "adventures", "in", "wonderland", "lewis", "carroll", 
  "the", "millennium", "fulcrum", "edition", "3.0", "chapter", "i", 
  "down", "rabbit-hole", "alice", "was", "beginning", "to", "get", 
  "very", "tired", "of", "sitting", "by", "her", "sister", "on", 
  "bank", "and", "having", "nothing", "do", "once", "or", "twice", 
  "she", "had", "peeped", "into", "book", "reading", "but", "it", 
  "no", "pictures", "conversations", "what", "is", "use", "a", 
  "thought", "without", "conversation", "so", "considering", "own", 
  "mind", "as", "well", "could", "for", "hot", "day", "made", "feel", 
  "sleepy", "stupid", "whether", "pleasure", "making", "daisy-chain", 
  "would", "be", "worth", "trouble", "getting", "up", "picking", 
  "daisies", "when", "suddenly", "white", "rabbit", "with", "pink", 
  "eyes", "ran", "close"}, {"there", "was", "nothing", "so", "very", 
  "remarkable", "in", "that", "nor", "did", "alice", "think", "it", 
  "much", "out", "of", "the", "way", "to", "hear", "rabbit", "say", 
  "itself", "oh", "dear"}}

How can I go through each elements and delete those words that contain "'", "-" or they are number like 3.0 The outcome should look like:

{{"adventures", "in", "wonderland", "lewis", "carroll", 
      "the", "millennium", "fulcrum", "edition", "chapter", "i", 
      "down", "alice", "was", "beginning", "to", "get", 
      "very", "tired", "of", "sitting", "by", "her", "sister", "on", 
      "bank", "and", "having", "nothing", "do", "once", "or", "twice", 
      "she", "had", "peeped", "into", "book", "reading", "but", "it", 
      "no", "pictures", "conversations", "what", "is", "use", "a", 
      "thought", "without", "conversation", "so", "considering", "own", 
      "mind", "as", "well", "could", "for", "hot", "day", "made", "feel", 
      "sleepy", "stupid", "whether", "pleasure", "making", 
      "would", "be", "worth", "trouble", "getting", "up", "picking", 
      "daisies", "when", "suddenly", "white", "rabbit", "with", "pink", 
      "eyes", "ran", "close"}, {"there", "was", "nothing", "so", "very", 
      "remarkable", "in", "that", "nor", "did", "alice", "think", "it", 
      "much", "out", "of", "the", "way", "to", "hear", "rabbit", "say", 
      "itself", "oh", "dear"}}

I have tried DeleteCases[l,_?ContainsAll[{"'"}]] yet it did not work.

$\endgroup$
  • 3
    $\begingroup$ Because they are strings, check StringContainsQ $\endgroup$ – Kuba Feb 5 at 13:32
  • $\begingroup$ Thanks @gwr it does the job $\endgroup$ – William Feb 5 at 13:41
  • 4
    $\begingroup$ Select[LetterQ] /@ l $\endgroup$ – Alan Feb 5 at 13:47
3
$\begingroup$
Pick[l, StringFreeQ["-" | "'" | DigitCharacter] /@ l]

{{"adventures", "in", "wonderland", "lewis", "carroll", "the", "millennium", "fulcrum", "edition", "chapter", "i", "down", "alice", "was", "beginning", "to", "get", "very", "tired", "of", "sitting", "by", "her", "sister", "on", "bank", "and", "having", "nothing", "do", "once", "or", "twice", "she", "had", "peeped", "into", "book", "reading", "but", "it", "no", "pictures", "conversations", "what", "is", "use", "a", "thought", "without", "conversation", "so", "considering", "own", "mind", "as", "well", "could", "for", "hot", "day", "made", "feel", "sleepy", "stupid", "whether", "pleasure", "making", "would", "be", "worth", "trouble", "getting", "up", "picking", "daisies", "when", "suddenly", "white", "rabbit", "with", "pink", "eyes", "ran", "close"},
{"there", "was", "nothing", "so", "very", "remarkable", "in", "that", "nor", "did", "alice", "think", "it", "much", "out", "of", "the", "way", "to", "hear", "rabbit", "say", "itself", "oh", "dear"}}}

This is several times faster than DeleteCases+StringContainsQ combination on input l:

Pick[l, StringFreeQ["-" | "'" | DigitCharacter] /@ l] // RepeatedTiming // First

0.000042

DeleteCases[l,  x_String /; StringContainsQ[x, "'" | "-" | NumberString], Infinity] //
  RepeatedTiming // First

0.00025

$\endgroup$
  • $\begingroup$ (+1) Good old Pick made me look up this old post: (2). Is it still relevant? $\endgroup$ – gwr Feb 6 at 8:06
  • $\begingroup$ @gwr, thank you for the upvote. Re Pick vs Cases vs Select, I am not sure if Pick is still the fastest of the three (my impression (based on few cases) is that Cases and Select has improved since v9.) $\endgroup$ – kglr Feb 6 at 8:24
3
$\begingroup$

To make this post complete I have moved my comment here as an answer:

DeleteCases[ l, x_String /; StringContainsQ[x, "'" | "-" | NumberString ] , Infinity]

or

DeleteCases[l, _String?(StringContainsQ[#, "'" | "-" | NumberString ] &), Infinity]

Using RepeatedTiming reveals that the Condition version is minimally faster than the PatternTest version. It takes about 0.00021 secs on my machine. Note, that looking for patterns with head String only (e.g. _String) will speed up the process.

Alan's suggestion ( Select[LetterQ] /@ l ) is very concise and readable but will take twice as long (0.00041 secs) on my machine. Probably LetterQ does a bit more checks?

Update

kglr nicely shows how fast Pick is here and I linked an old post for those interested on why that may be. As LetterQ does more testing than the three Alternatives given above it may be worth mentioning that DigitCharacter as used by kglr also is faster than NumberString:

DeleteCases[l, x_String /; StringContainsQ[x, "'" | "-" | NumberString], Infinity] // RepeatedTiming // First

0.00020

DeleteCases[l, x_String /; StringContainsQ[x, "'" | "-" | NumberString], Infinity] // RepeatedTiming // First

0.00014

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.